Merge remote-tracking branch 'origin/develop' into fix-at-room

This commit is contained in:
Florian Renaud 2023-02-06 09:35:16 +01:00
commit e1086669c7
3605 changed files with 101473 additions and 33110 deletions

View file

@ -770,7 +770,7 @@ ij_kotlin_align_multiline_extends_list = false
ij_kotlin_align_multiline_method_parentheses = false
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = false
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = false
ij_kotlin_assignment_wrap = off
ij_kotlin_blank_lines_after_class_header = 0

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
**/src/androidTest/assets/*.realm filter=lfs diff=lfs merge=lfs -text

View file

@ -5,7 +5,7 @@ body:
- type: markdown
attributes:
value: |
Thank you for taking the time to propose a new feature or make a suggestion.
Thank you for taking the time to propose an enhancement to an existing feature. If you would like to propose a new feature or a major cross-platform change, please [start a discussion here](https://github.com/vector-im/element-meta/discussions/new?category=ideas).
- type: textarea
id: usecase
attributes:

View file

@ -10,7 +10,6 @@ body:
id: checklist
attributes:
label: Release checklist
description: For the template example, we are releasing the version 1.2.3. Replace 1.2.3 with the version in the issue body.
placeholder: |
If you are reading this, you have deleted the content of the release template: undo the deletion or start again.
value: |
@ -20,32 +19,11 @@ body:
- [ ] Check the update of the store descriptions (using Google Translate if necessary) to ensure that the changes are acceptable to be published to the stores.
- [ ] While Weblate is locked, and after the PR from Weblate has been merged, handle all the TODOs in the main `strings.xml` file
- [ ] Run the script `./tools/release/pushPlayStoreMetaData.sh`. You can check in the GooglePlay console the Activity log to check the effect.
- [ ] Ensure all [the required PRs](https://github.com/vector-im/element-android/pulls?q=is%3Aopen+is%3Apr+label%3AZ-NextRelease) have been merged
### Do the release
- [ ] Make sure `develop` and `main` are up to date (git pull)
- [ ] Checkout develop and create a release with gitflow, branch name `release/1.2.3`
- [ ] Check the crashes from the PlayStore
- [ ] Check the rageshake with the current dev version: https://github.com/matrix-org/element-android-rageshakes/labels/1.2.3-dev
- [ ] Run the integration test, and especially `UiAllScreensSanityTest.allScreensTest()`
- [ ] Create an account on matrix.org and do some smoke tests that the sanity test does not cover like: 1-1 call, 1-1 video call, Jitsi call for instance
- [ ] Run towncrier: `towncrier --version v1.2.3 --draft` (remove `--draft` do write the file CHANGES.md)
- [ ] Check that the folder `changelog.d` is empty. It can happen that some remaining files stay here
- [ ] Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things
- [ ] Add file for fastlane under ./fastlane/metadata/android/en-US/changelogs
- [ ] (optional) Push the branch and start a draft PR (will not be merged), to check that the CI is happy with all the changes.
- [ ] Finish release with gitflow, delete the draft PR (if created)
- [ ] Push `main` and the new tag `v1.2.3` to origin
- [ ] Checkout `develop`
- [ ] Increase version (versionPatch + 2) in `./vector/build.gradle`
- [ ] Change the value of SDK_VERSION in the file `./matrix-sdk-android/build.gradle`
- [ ] Commit and push `develop`
- [ ] Wait for [Buildkite](https://buildkite.com/matrix-dot-org/element-android/builds?branch=main) to build the `main` branch.
- [ ] Run the script `~/scripts/releaseElement.sh`. It will download the APKs from Buildkite check them and sign them.
- [ ] Install the APK on your phone to check that the upgrade went well (no init sync, etc.)
- [ ] Create the release on gitHub [from the tag](https://github.com/vector-im/element-android/tags), copy paste the block from the file CHANGES.md
- [ ] Add the 4 signed APKs to the GitHub release
- [ ] Ping the Android Internal room
- [ ] Run the script ./tools/release/releaseScript.sh and follow the steps.
### Once tested and validated internally
@ -82,29 +60,9 @@ body:
The SDK2 and the sample app are released only when Element has been pushed to production.
- [ ] Checkout the `main` branch on Element Android project
- [ ] On the [SDK2 project](https://github.com/matrix-org/matrix-android-sdk2), run the script ./tools/releaseScript.sh and follow the instructions.
#### On the SDK2 project
https://github.com/matrix-org/matrix-android-sdk2
- [ ] Create a release with GitFlow
- [ ] Update the value of VERSION_NAME in the file gradle.properties
- [ ] Update the files `./build.gradle` and `./gradle/gradle-wrapper.properties` manually, to use the latest version for the dependency. You can get inspired by the same files on Element Android project.
- [ ] Run the script `./tools/import_from_element.sh`
- [ ] Check the diff in the file `./matrix-sdk-android/build.gradle` and restore what may have been erased (in particular the line `apply plugin: "com.vanniktech.maven.publish"` and the line about the version)
- [ ] Let the script finish to build the library
- [ ] Update the file `CHANGES.md`
- [ ] Finish the release using GitFlow
- [ ] Push the branch `main`, the new tag and the branch `develop` to origin
##### Release on MavenCentral
- [ ] Checkout the branch `main`
- [ ] Run the command `./gradlew publish --no-daemon --no-parallel`. You'll need some non-public element to do so
- [ ] Run the command `./gradlew closeAndReleaseRepository`. If it is working well, you can jump directly to the final step of this section.
If `./gradlew closeAndReleaseRepository` fails (for instance, several repositories are waiting to be handled), you have to close and release the repository manually. Do the following steps:
Note: if the step `./gradlew closeAndReleaseRepository` fails (for instance, several repositories are waiting to be handled), you have to close and release the repository manually. Do the following steps:
- [ ] Connect to https://s01.oss.sonatype.org
- [ ] Click on Staging Repositories and check the the files have been uploaded
@ -112,15 +70,6 @@ body:
- [ ] Wait (check Activity tab until step "Repository closed" is displayed)
- [ ] Click on release. The staging repository will disappear
Final step
- [ ] Check that the release is available in https://repo1.maven.org/maven2/org/matrix/android/matrix-android-sdk2/ (it can take a few minutes)
##### Release on GitHub
- [ ] Create the release on GitHub from [the tag](https://github.com/matrix-org/matrix-android-sdk2/tags)
- [ ] Upload the AAR on the GitHub release
### Android SDK2 sample
https://github.com/matrix-org/matrix-android-sdk2-sample

View file

@ -7,10 +7,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
CI_GRADLE_ARG_PROPERTIES: >
-Porg.gradle.jvmargs=-Xmx4g
-Porg.gradle.parallel=false
--no-daemon
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
debug:
@ -27,22 +25,18 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
- name: Configure gradle
uses: gradle/gradle-build-action@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
- name: Assemble ${{ matrix.target }} debug apk
run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES --stacktrace
run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES
- name: Upload ${{ matrix.target }} debug APKs
uses: actions/upload-artifact@v3
with:
name: vector-${{ matrix.target }}-debug
path: |
vector/build/outputs/apk/*/debug/*.apk
vector-app/build/outputs/apk/*/debug/*.apk
release:
name: Build unsigned GPlay APKs
@ -52,22 +46,18 @@ jobs:
cancel-in-progress: ${{ github.ref != 'refs/head/main' }}
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
- name: Configure gradle
uses: gradle/gradle-build-action@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
- name: Assemble GPlay unsigned apk
run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES --stacktrace
run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload Gplay unsigned APKs
uses: actions/upload-artifact@v3
with:
name: vector-gplay-release-unsigned
path: |
vector/build/outputs/apk/*/release/*.apk
vector-app/build/outputs/apk/*/release/*.apk
exodus:
runs-on: ubuntu-latest

20
.github/workflows/danger.yml vendored Normal file
View file

@ -0,0 +1,20 @@
name: Danger CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
name: Danger
steps:
- uses: actions/checkout@v3
- run: |
npm install --save-dev @babel/plugin-transform-flow-strip-types
- name: Danger
uses: danger/danger-js@11.2.2
with:
args: "--dangerfile ./tools/danger/dangerfile.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
# Fallback for forks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Build docs
run: ./gradlew dokkaHtml

View file

@ -1,5 +1,8 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
on:
pull_request: { }
push:
branches: [ main, develop ]
jobs:
validation:

42
.github/workflows/nightly.yml vendored Normal file
View file

@ -0,0 +1,42 @@
name: Build and release nightly APK
on:
schedule:
# Every nights at 4
- cron: "0 4 * * *"
env:
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
nightly:
name: Build and publish nightly Gplay APK to Firebase
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Configure gradle
uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
- name: Install towncrier
run: |
python3 -m pip install towncrier
- name: Prepare changelog file
run: |
mv towncrier.toml towncrier.toml.bak
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
rm towncrier.toml.bak
yes n | towncrier build --version nightly
- name: Build and upload Gplay Nightly APK
run: |
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
env:
ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }}
FIREBASE_TOKEN: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_FIREBASE_TOKEN }}

View file

@ -10,10 +10,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
CI_GRADLE_ARG_PROPERTIES: >
-Porg.gradle.jvmargs=-Xmx4g
-Porg.gradle.parallel=false
--no-daemon
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
@ -33,7 +31,8 @@ jobs:
ui-tests:
name: UI Tests (Synapse)
needs: should-i-run
runs-on: macos-latest
runs-on: buildjet-4vcpu-ubuntu-2204
timeout-minutes: 90 # We might need to increase it if the time for tests grows
strategy:
fail-fast: false
matrix:
@ -45,25 +44,21 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- uses: actions/cache@v3
- uses: actions/setup-java@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
distribution: 'adopt'
java-version: '11'
- name: Configure gradle
uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
- name: Start synapse server
uses: michaelkaye/setup-matrix-synapse@v1.0.3
uses: michaelkaye/setup-matrix-synapse@v1.0.4
with:
uploadLogs: true
httpPort: 8080
disableRateLimiting: true
public_baseurl: "http://10.0.2.2:8080/"
- uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '11'
- name: Run sanity tests on API ${{ matrix.api-level }}
uses: reactivecircus/android-emulator-runner@v2
with:
@ -96,7 +91,7 @@ jobs:
needs:
- should-i-run
- ui-tests
if: always() && (needs.should-i-run.result == 'success' ) && ((needs.codecov-units.result != 'success' ) || (needs.ui-tests.result != 'success') || (needs.integration-tests.result != 'success'))
if: always() && (needs.should-i-run.result == 'success' ) && (needs.ui-tests.result != 'success')
# No concurrency required, runs every time on a schedule.
steps:
- uses: michaelkaye/matrix-hookshot-action@v1.0.0

View file

@ -7,10 +7,8 @@ on:
# Enrich gradle.properties for CI/CD
env:
CI_GRADLE_ARG_PROPERTIES: >
-Porg.gradle.jvmargs=-Xmx4g
-Porg.gradle.parallel=false
--no-daemon
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -XX:MaxPermSize=512m -Dkotlin.daemon.jvm.options="-Xmx2g" -Dkotlin.incremental=false
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
jobs:
check:
@ -29,80 +27,52 @@ jobs:
- uses: actions/checkout@v3
- name: Run knit
run: |
./gradlew knit
./gradlew knitCheck $CI_GRADLE_ARG_PROPERTIES
# ktlint for all the modules
ktlint:
name: Kotlin Linter
# Check the project: ktlint, detekt, lint
lint:
name: Android Linter
runs-on: ubuntu-latest
# Allow all jobs on main and develop. Just one per PR.
concurrency:
group: ${{ github.ref == 'refs/heads/main' && format('ktlint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('ktlint-develop-{0}', github.sha) || format('ktlint-{0}', github.ref) }}
group: ${{ github.ref == 'refs/heads/main' && format('lint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('lint-develop-{0}', github.sha) || format('lint-{0}', github.ref) }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- name: Run ktlint
run: |
./gradlew ktlintCheck --continue
./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES --continue
- name: Run detekt
if: always()
run: |
./gradlew detekt $CI_GRADLE_ARG_PROPERTIES
- name: Run lint
# Not always, if ktlint or detekt fail, avoid running the long lint check.
run: |
./gradlew vector-app:lintGplayRelease $CI_GRADLE_ARG_PROPERTIES
./gradlew vector-app:lintFdroidRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports
if: always()
uses: actions/upload-artifact@v3
with:
name: ktlinting-report
name: linting-report
path: |
*/build/reports/ktlint/ktlint*/ktlint*.txt
- name: Handle Results
*/build/reports/**/*.*
- name: Prepare Danger
if: always()
id: ktlint-results
run: |
results="$(cat */*/build/reports/ktlint/ktlint*/ktlint*.txt */build/reports/ktlint/ktlint*/ktlint*.txt | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g")"
if [ -z "$results" ]; then
echo "::set-output name=add_comment::false"
else
body="👎\`Failed${results}\`"
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
body="$( echo $body | sed 's/\/home\/runner\/work\/element-android\/element-android\//\`<br\/>\`/g')"
body="$( echo $body | sed 's/\/src\/main\/java\// 🔸 /g')"
body="$( echo $body | sed 's/im\/vector\/app\///g')"
body="$( echo $body | sed 's/im\/vector\/lib\/attachmentviewer\///g')"
body="$( echo $body | sed 's/im\/vector\/lib\/multipicker\///g')"
body="$( echo $body | sed 's/im\/vector\/lib\///g')"
body="$( echo $body | sed 's/org\/matrix\/android\/sdk\///g')"
body="$( echo $body | sed 's/\/src\/androidTest\/java\// 🔸 /g')"
echo "::set-output name=add_comment::true"
echo "::set-output name=body::$body"
fi
- name: Find Comment
if: always() && github.event_name == 'pull_request'
uses: peter-evans/find-comment@v2
id: fc
npm install --save-dev @babel/core
npm install --save-dev @babel/plugin-transform-flow-strip-types
yarn add danger-plugin-lint-report --dev
- name: Danger lint
if: always()
uses: danger/danger-js@11.2.2
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Ktlint Results
- name: Add comment if needed
if: always() && github.event_name == 'pull_request' && steps.ktlint-results.outputs.add_comment == 'true'
uses: peter-evans/create-or-update-comment@v2
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### Ktlint Results
${{ steps.ktlint-results.outputs.body }}
edit-mode: replace
- name: Delete comment if needed
if: always() && github.event_name == 'pull_request' && steps.fc.outputs.comment-id != '' && steps.ktlint-results.outputs.add_comment == 'false'
uses: actions/github-script@v3
with:
script: |
github.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.fc.outputs.comment-id }}
})
args: "--dangerfile ./tools/danger/dangerfile-lint.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
# Fallback for forks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Gradle dependency analysis using https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin
dependency-analysis:
@ -122,84 +92,3 @@ jobs:
with:
name: dependency-analysis
path: build/reports/dependency-check-report.html
# Lint for main module
android-lint:
name: Android Linter
runs-on: ubuntu-latest
# Allow all jobs on main and develop. Just one per PR.
concurrency:
group: ${{ github.ref == 'refs/heads/main' && format('android-lint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('android-lint-develop-{0}', github.sha) || format('android-lint-{0}', github.ref) }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Lint analysis
run: ./gradlew clean :vector:lint --stacktrace $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports
if: always()
uses: actions/upload-artifact@v3
with:
name: lint-report
path: |
vector/build/reports/*.*
# Lint for Gplay and Fdroid release APK
apk-lint:
name: Lint APK (${{ matrix.target }})
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/main'
strategy:
fail-fast: false
matrix:
target: [ Gplay, Fdroid ]
# Allow all jobs on develop. Just one per PR.
concurrency:
group: ${{ github.ref == 'refs/heads/develop' && format('apk-lint-develop-{0}-{1}', matrix.target, github.sha) || format('apk-lint-{0}-{1}', matrix.target, github.ref) }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Lint ${{ matrix.target }} release
run: ./gradlew clean lint${{ matrix.target }}Release --stacktrace $CI_GRADLE_ARG_PROPERTIES
- name: Upload ${{ matrix.target }} linting report
if: always()
uses: actions/upload-artifact@v3
with:
name: release-lint-report-${{ matrix.target }}
path: |
vector/build/reports/*.*
detekt:
name: Detekt Analysis
runs-on: ubuntu-latest
# Allow all jobs on main and develop. Just one per PR.
concurrency:
group: ${{ github.ref == 'refs/heads/main' && format('detekt-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('detekt-develop-{0}', github.sha) || format('detekt-{0}', github.ref) }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- name: Run detekt
run: |
./gradlew detekt $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports
if: always()
uses: actions/upload-artifact@v3
with:
name: detekt-report
path: |
*/build/reports/detekt/detekt.html

View file

@ -7,15 +7,17 @@ on:
# Enrich gradle.properties for CI/CD
env:
CI_GRADLE_ARG_PROPERTIES: >
-Porg.gradle.jvmargs=-Xmx4g
-Porg.gradle.parallel=false
--no-daemon
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 4 --no-daemon
jobs:
tests:
name: Runs all tests
runs-on: macos-latest # for the emulator
runs-on: buildjet-4vcpu-ubuntu-2204
timeout-minutes: 90 # We might need to increase it if the time for tests grows
strategy:
matrix:
api-level: [28]
# Allow all jobs on main and develop. Just one per PR.
concurrency:
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
@ -23,59 +25,91 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
lfs: true
fetch-depth: 0
- uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '11'
- uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
gradle-home-cache-cleanup: ${{ github.ref == 'refs/heads/develop' }}
- name: Run screenshot tests
run: ./gradlew verifyScreenshots $CI_GRADLE_ARG_PROPERTIES
- name: Archive Screenshot Results on Error
if: failure()
uses: actions/upload-artifact@v3
with:
name: screenshot-results
path: |
**/out/failures/
**/build/reports/tests/*UnitTest/
- uses: actions/setup-python@v4
with:
python-version: 3.8
- uses: michaelkaye/setup-matrix-synapse@v1.0.3
- uses: michaelkaye/setup-matrix-synapse@v1.0.4
with:
uploadLogs: true
httpPort: 8080
disableRateLimiting: true
public_baseurl: "http://10.0.2.2:8080/"
- name: Run all the codecoverage tests at once
id: tests
uses: reactivecircus/android-emulator-runner@v2
continue-on-error: true
# continue-on-error: true
with:
api-level: 28
api-level: ${{ matrix.api-level }}
arch: x86
profile: Nexus 5X
target: playstore
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
emulator-build: 7425822
# emulator-build: 7425822
script: |
./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
./gradlew instrumentationTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves stes.tests.outcome = 'failure'
- name: Run all the codecoverage tests at once (retry if emulator failed)
uses: reactivecircus/android-emulator-runner@v2
if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves steps.tests.outcome = 'failure'
### - name: Run all the codecoverage tests at once (retry if emulator failed)
### uses: reactivecircus/android-emulator-runner@v2
### if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
### with:
### api-level: 28
### arch: x86
### profile: Nexus 5X
### force-avd-creation: false
### emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
### disable-animations: true
### emulator-build: 7425822
### script: |
### ./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
### ./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
### ./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
### ./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
- name: Upload Integration Test Report Log
uses: actions/upload-artifact@v3
if: always()
with:
api-level: 28
arch: x86
profile: Nexus 5X
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
emulator-build: 7425822
script: |
./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
./gradlew instrumentationTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES
./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES
- run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES
if: always() # we may have failed a previous step and retried, that's OK
name: integration-test-error-results
path: |
*/build/outputs/androidTest-results/connected/
*/build/reports/androidTests/connected/
# we may have failed a previous step and retried, that's OK
- name: Publish results to Sonar
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
GITHUB_TOKEN: ${{ secrets.SONARQUBE_GITHUB_API_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }}
if: ${{ always() && env.GITHUB_TOKEN != '' && env.SONAR_TOKEN != '' && env.ORG_GRADLE_PROJECT_SONAR_LOGIN != '' }}
run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES
- name: Format unit test results
if: always()
@ -105,14 +139,10 @@ jobs:
# with:
# distribution: 'adopt'
# java-version: 11
# - uses: actions/cache@v3
# - name: Configure gradle
# uses: gradle/gradle-build-action@v2
# with:
# path: |
# ~/.gradle/caches
# ~/.gradle/wrapper
# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
# restore-keys: |
# ${{ runner.os }}-gradle-
# cache-read-only: ${{ github.ref != 'refs/heads/develop' }}
# - name: Build Android Tests
# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES

View file

@ -10,7 +10,7 @@ jobs:
# Skip in forks
if: github.repository == 'vector-im/element-android'
steps:
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
- uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43
with:
project: Issue triage
column: Incoming

View file

@ -17,7 +17,8 @@ jobs:
contains(github.event.issue.labels.*.name, 'Z-IA') ||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
contains(github.event.issue.labels.*.name, 'A-Tags')
contains(github.event.issue.labels.*.name, 'A-Tags') ||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor')
steps:
- uses: actions/github-script@v5
with:
@ -29,6 +30,23 @@ jobs:
labels: ['Z-Labs']
})
apply_Help-Wanted_label:
name: Add "Help Wanted" label to all "good first issue" and Hacktoberfest
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'good first issue') ||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
steps:
- uses: actions/github-script@v5
with:
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['Help Wanted']
})
move_needs_info_issues:
name: X-Needs-Info issues to Need info column on triage board
runs-on: ubuntu-latest
@ -42,8 +60,8 @@ jobs:
column-name: "Need info"
label-name: "X-Needs-Info"
add_priority_design_issues_to_project:
name: P1 X-Needs-Design to Design project board
add_design_issues_to_project:
name: X-Needs-Design to Design project board
runs-on: ubuntu-latest
# Skip in forks
if: >
@ -52,10 +70,9 @@ jobs:
(contains(github.event.issue.labels.*.name, 'S-Critical') &&
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
contains(github.event.issue.labels.*.name, 'S-Major') &&
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
contains(github.event.issue.labels.*.name, 'A11y') &&
contains(github.event.issue.labels.*.name, 'O-Frequent'))
(contains(github.event.issue.labels.*.name, 'S-Major') &&
contains(github.event.issue.labels.*.name, 'O-Frequent')) ||
contains(github.event.issue.labels.*.name, 'A11y'))
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
@ -63,8 +80,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -72,7 +89,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc0sUA"
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
add_product_issues:
@ -87,8 +104,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -96,7 +113,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
delight_issues_to_board:
@ -105,15 +122,16 @@ jobs:
# Skip in forks
if: >
github.repository == 'vector-im/element-android' &&
(contains(github.event.issue.labels.*.name, 'Team: Delight'))
(contains(github.event.issue.labels.*.name, 'Team: Delight') ||
contains(github.event.issue.labels.*.name, 'Z-AppLayout'))
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -121,7 +139,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc1HvQ"
PROJECT_ID: "PVT_kwDOAM0swc1HvQ"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_voice-message_issues:
@ -137,8 +155,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -146,34 +164,8 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc2KCw"
PROJECT_ID: "PVT_kwDOAM0swc2KCw"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_threads_issues:
name: A-Threads to Thread board
runs-on: ubuntu-latest
# Skip in forks
if: >
github.repository == 'vector-im/element-android' &&
contains(github.event.issue.labels.*.name, 'A-Threads')
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc0rRA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_message_bubbles_issues:
name: A-Message-Bubbles to Message bubbles board
runs-on: ubuntu-latest
@ -187,8 +179,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -196,7 +188,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc3m-g"
PROJECT_ID: "PVT_kwDOAM0swc3m-g"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_ftue_issues:
@ -212,8 +204,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -221,7 +213,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAqVx"
PROJECT_ID: "PVT_kwDOAM0swc4AAqVx"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_WTF_issues:
@ -237,8 +229,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -246,7 +238,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AArk0"
PROJECT_ID: "PVT_kwDOAM0swc4AArk0"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_element_x_issues:
@ -255,17 +247,20 @@ jobs:
# Skip in forks
if: >
github.repository == 'vector-im/element-android' &&
(contains(github.event.issue.labels.*.name, 'Z-ElementX-Alpha') ||
contains(github.event.issue.labels.*.name, 'Z-ElementX-Beta') ||
contains(github.event.issue.labels.*.name, 'Z-ElementX'))
(contains(github.event.issue.labels.*.name, 'Z-BBQ-Alpha') ||
contains(github.event.issue.labels.*.name, 'Z-BBQ-Beta') ||
contains(github.event.issue.labels.*.name, 'Z-BBQ-Release') ||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Alpha') ||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Beta') ||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Release'))
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -273,5 +268,107 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4ABTXY"
PROJECT_ID: "PVT_kwDOAM0swc4ABTXY"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features1:
name: Add labelled issues to PS features team 1
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'A-Polls') ||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
(contains(github.event.issue.labels.*.name, 'A-Voice-Messages') &&
!contains(github.event.issue.labels.*.name, 'A-Broadcast')) ||
(contains(github.event.issue.labels.*.name, 'A-Session-Mgmt') &&
contains(github.event.issue.labels.*.name, 'A-User-Settings'))
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKF"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features2:
name: Add labelled issues to PS features team 2
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'A-DM-Start') ||
contains(github.event.issue.labels.*.name, 'A-Broadcast')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKd"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features3:
name: Add labelled issues to PS features team 3
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKW"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
voip:
name: Add labelled issues to VoIP project board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'Team: VoIP')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4ABMIk"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}

View file

@ -60,8 +60,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!, $contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -69,7 +69,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.pull_request.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc0sUA"
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
TEAM: "design"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
@ -129,8 +129,8 @@ jobs:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!, $contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
@ -138,6 +138,6 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.pull_request.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
TEAM: "product"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}

View file

@ -24,10 +24,10 @@ jobs:
contains(github.event.issue.labels.*.name, 'A11y') &&
contains(github.event.issue.labels.*.name, 'O-Frequent'))
steps:
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
- uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43
with:
project: Android App Team
column: P1
column: Important Issues & Topics (P1)
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
P1_issues_to_crypto_team_workboard:
@ -50,7 +50,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'A11y') &&
contains(github.event.issue.labels.*.name, 'O-Frequent')))
steps:
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
- uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43
with:
project: Crypto Team
column: Ready

View file

@ -28,7 +28,7 @@ jobs:
echo "ALREADY_IN_BOARD=false" >> $GITHUB_ENV
fi
- name: Move issue
uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43
if: ${{ env.ALREADY_IN_BOARD == 'true' }}
with:
project: Issue triage

15
.github/workflows/validate-lfs.yml vendored Normal file
View file

@ -0,0 +1,15 @@
name: Validate Git LFS
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
name: Validate
steps:
- uses: actions/checkout@v3
with:
lfs: 'true'
- run: |
./tools/validate_lfs.sh

6
.gitignore vendored
View file

@ -17,3 +17,9 @@
/fastlane/report.xml
/**/build
# Added by yarn
/package.json
/yarn.lock
/node_modules
**/out/failures

View file

@ -1,18 +0,0 @@
# FTR: Configuration on https://travis-ci.org/github/vector-im/element-android/settings
#
# - Build only if .travis.yml is present -> On
# - Limit concurrent jobs -> Off
# - Build pushed branches -> On (build the branch)
# - Build pushed pull request -> On (build the PR after auto-merge)
#
# - Auto cancel branch builds -> On
# - Auto cancel pull request builds -> On
sudo: false
notifications:
email: false
# Just run a simple script here
script:
- ./tools/travis/check_pr.sh

View file

@ -1,3 +1,730 @@
Changes in Element v1.5.22 (2023-01-25)
=======================================
Features ✨
----------
- [Poll] Warning message on decryption failure of some events ([#7824](https://github.com/vector-im/element-android/issues/7824))
- [Poll] Render ended polls ([#7900](https://github.com/vector-im/element-android/issues/7900))
- [Rich text editor] Update list item bullet appearance ([#7930](https://github.com/vector-im/element-android/issues/7930))
- [Voice Broadcast] Handle connection errors while recording ([#7890](https://github.com/vector-im/element-android/issues/7890))
- [Voice Broadcast] Use MSC3912 to delete server side all the related events ([#7967](https://github.com/vector-im/element-android/issues/7967))
Bugfixes 🐛
----------
- Fix OOM crashes. ([#7962](https://github.com/vector-im/element-android/issues/7962))
- Fix can't get out of a verification dialog ([#4025](https://github.com/vector-im/element-android/issues/4025))
- Fix rendering of edited polls ([#7938](https://github.com/vector-im/element-android/issues/7938))
- [Voice Broadcast] Fix unexpected "live broadcast" in the room list ([#7832](https://github.com/vector-im/element-android/issues/7832))
- Send voice message should not be allowed during a voice broadcast recording ([#7895](https://github.com/vector-im/element-android/issues/7895))
- Voice Broadcast - Fix playback scrubbing not working if the playback is in a stopped state ([#7961](https://github.com/vector-im/element-android/issues/7961))
- Handle exceptions when listening a voice broadcast ([#7829](https://github.com/vector-im/element-android/issues/7829))
In development 🚧
----------------
- [Voice Broadcast] Only display a notification on the first voice chunk ([#7845](https://github.com/vector-im/element-android/issues/7845))
- [Poll] History list: Load more UI mechanism ([#7864](https://github.com/vector-im/element-android/issues/7864))
SDK API changes ⚠️
------------------
- Implement [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3912): Relation-based redactions ([#7988](https://github.com/vector-im/element-android/issues/7988))
Other changes
-------------
- Upgrade to Kotlin 1.8 ([#7936](https://github.com/vector-im/element-android/issues/7936))
- Sentry: Report sync duration and metrics for initial sync and for sync after pause. Not for regular sync. ([#7960](https://github.com/vector-im/element-android/issues/7960))
- [Voice Broadcast] Rework internal media players coordination ([#7979](https://github.com/vector-im/element-android/issues/7979))
- Support reactions on Voice Broadcast ([#7807](https://github.com/vector-im/element-android/issues/7807))
- Pause voice broadcast listening on new VB recording ([#7830](https://github.com/vector-im/element-android/issues/7830))
- Tapping slightly left or right of the 30s buttons highlights the whole cell instead of registering as button presses ([#7929](https://github.com/vector-im/element-android/issues/7929))
Changes in Element v1.5.20 (2023-01-10)
=======================================
Features ✨
----------
- "[Rich text editor] Add list formatting buttons to the rich text editor" ([#7887](https://github.com/vector-im/element-android/issues/7887))
Bugfixes 🐛
----------
- ReplyTo are not updated if the original message is edited or deleted. ([#5546](https://github.com/vector-im/element-android/issues/5546))
- Observe ViewEvents only when resumed and ensure ViewEvents are not lost. ([#7724](https://github.com/vector-im/element-android/issues/7724))
- [Session manager] Missing info when a session does not support encryption ([#7853](https://github.com/vector-im/element-android/issues/7853))
- Reduce number of crypto database transactions when handling the sync response ([#7879](https://github.com/vector-im/element-android/issues/7879))
- [Voice Broadcast] Stop listening if we reach the last received chunk and there is no last sequence number ([#7899](https://github.com/vector-im/element-android/issues/7899))
- Handle network error on API `rooms/{roomId}/threads` ([#7913](https://github.com/vector-im/element-android/issues/7913))
In development 🚧
----------------
- [Poll] Render active polls list of a room
- [Poll] Render past polls list of a room ([#7864](https://github.com/vector-im/element-android/issues/7864))
Other changes
-------------
- fix: increase font size for messages ([#5717](https://github.com/vector-im/element-android/issues/5717))
- Add trim to username input on the app side and SDK side when sign-in ([#7111](https://github.com/vector-im/element-android/issues/7111))
Changes in Element v1.5.18 (2023-01-02)
=======================================
This release fixes a bunch of recent regressions. Most of them were not pushed to production hopefully. Current production version is 1.5.11.
Threads are now enabled by default, and this may let the application perform an initial sync.
Testers on the PlayStore may have experimented some issues like empty room list, or incomplete room state (room name missing, etc.), or even crashing due to initial sync not using lazy loading of room members. All those issues have been fixed, but to fix your current state, please clear cache once you get the release 1.5.18.
Bugfixes 🐛
----------
- Start DM will create a deadlock if user profile was never loaded ([#7870](https://github.com/vector-im/element-android/issues/7870))
Changes in Element v1.5.16 (2022-12-29)
======================================
Features ✨
----------
- [Rich text editor] Add support for links ([#7746](https://github.com/vector-im/element-android/issues/7746))
- [Poll] When a poll is ended, use /relations API to ensure poll results are correct ([#7767](https://github.com/vector-im/element-android/issues/7767))
- [Session manager] Security recommendations cards: whole view should be tappable ([#7795](https://github.com/vector-im/element-android/issues/7795))
- [Session manager] Other sessions list: header should not be sticky ([#7797](https://github.com/vector-im/element-android/issues/7797))
Bugfixes 🐛
----------
- Do not show typing notification of ignored users. ([#2965](https://github.com/vector-im/element-android/issues/2965))
- [Push Notifications, Threads] - quick reply to threaded notification now sent to thread except main timeline ([#7475](https://github.com/vector-im/element-android/issues/7475))
- [Session manager] Other sessions list: filter option is displayed when selection mode is enabled ([#7784](https://github.com/vector-im/element-android/issues/7784))
- [Session manager] Other sessions: Filter bottom sheet cut in landscape mode ([#7786](https://github.com/vector-im/element-android/issues/7786))
- Automatically show keyboard after learn more bottom sheet is dismissed ([#7790](https://github.com/vector-im/element-android/issues/7790))
- [Session Manager] Other sessions list: cannot select/deselect session by a long press when in select mode ([#7792](https://github.com/vector-im/element-android/issues/7792))
- Fix current session ip address visibility ([#7794](https://github.com/vector-im/element-android/issues/7794))
- Device Manager UI review fixes ([#7798](https://github.com/vector-im/element-android/issues/7798))
SDK API changes ⚠️
------------------
- [Sync] Sync Filter params are moved to MatrixConfiguration and will not be stored in session realm to avoid bug when session cache is cleared ([#7843](https://github.com/vector-im/element-android/issues/7843))
Other changes
-------------
- [Voice Broadcast] Replace the player timeline ([#7821](https://github.com/vector-im/element-android/issues/7821))
- Increase session manager test coverage ([#7836](https://github.com/vector-im/element-android/issues/7836))
Changes in Element v1.5.14 (2022-12-20)
=======================================
Bugfixes 🐛
----------
- ActiveSessionHolder is not supposed to start syncing. Instead, the MainActivity does it, if necessary. Fixes a race condition when clearing cache.
Changes in Element v1.5.13 (2022-12-19)
=======================================
Bugfixes 🐛
----------
- Add `largeHeap=true` in the manifest since we are seeing more crashes (OOM) when handling sync response.
Changes in Element v1.5.12 (2022-12-15)
=======================================
Features ✨
----------
- [Threads] - Threads Labs Flag is enabled by default and forced to be enabled for existing users, but sill can be disabled manually ([#5503](https://github.com/vector-im/element-android/issues/5503))
- [Session manager] Add action to signout all the other session ([#7693](https://github.com/vector-im/element-android/issues/7693))
- Remind unverified sessions with a banner once a week ([#7694](https://github.com/vector-im/element-android/issues/7694))
- [Session manager] Add actions to rename and signout current session ([#7697](https://github.com/vector-im/element-android/issues/7697))
- Voice Broadcast - Update last message in the room list ([#7719](https://github.com/vector-im/element-android/issues/7719))
- Delete unused client information from account data ([#7754](https://github.com/vector-im/element-android/issues/7754))
Bugfixes 🐛
----------
- Fix bad pills color background. For light and dark theme the color is now 61708B (iso EleWeb) ([#7274](https://github.com/vector-im/element-android/issues/7274))
- [Notifications] Fixed a bug when push notification was automatically dismissed while app is on background ([#7643](https://github.com/vector-im/element-android/issues/7643))
- ANR when asking to select the notification method ([#7653](https://github.com/vector-im/element-android/issues/7653))
- [Rich text editor] Fix design and spacing of rich text editor ([#7658](https://github.com/vector-im/element-android/issues/7658))
- [Rich text editor] Fix keyboard closing after collapsing editor ([#7659](https://github.com/vector-im/element-android/issues/7659))
- Rich Text Editor: fix several issues related to insets:
* Empty space displayed at the bottom when you don't have permissions to send messages into a room.
* Wrong insets being kept when you exit the room screen and the keyboard is displayed, then come back to it. ([#7680](https://github.com/vector-im/element-android/issues/7680))
- Fix crash in message composer when room is missing ([#7683](https://github.com/vector-im/element-android/issues/7683))
- Fix crash when invalid homeserver url is entered. ([#7684](https://github.com/vector-im/element-android/issues/7684))
- Rich Text Editor: improve performance when entering reply/edit/quote mode. ([#7691](https://github.com/vector-im/element-android/issues/7691))
- [Rich text editor] Add error tracking for rich text editor ([#7695](https://github.com/vector-im/element-android/issues/7695))
- Fix E2EE set up failure whilst signing in using QR code ([#7699](https://github.com/vector-im/element-android/issues/7699))
- Fix usage of unknown shield in room summary ([#7710](https://github.com/vector-im/element-android/issues/7710))
- Fix crash when the network is not available. ([#7725](https://github.com/vector-im/element-android/issues/7725))
- [Session manager] Sessions without encryption support should not prompt to verify ([#7733](https://github.com/vector-im/element-android/issues/7733))
- Fix issue of Scan QR code button sometimes not showing when it should be available ([#7737](https://github.com/vector-im/element-android/issues/7737))
- Verification request is not showing when verify session popup is displayed ([#7743](https://github.com/vector-im/element-android/issues/7743))
- Fix crash when inviting by email. ([#7744](https://github.com/vector-im/element-android/issues/7744))
- Revert usage of stable fields in live location sharing and polls ([#7751](https://github.com/vector-im/element-android/issues/7751))
- [Poll] Poll end event is not recognized ([#7753](https://github.com/vector-im/element-android/issues/7753))
- [Push Notifications] When push notification for threaded message is clicked, thread timeline will be opened instead of room's main timeline ([#7770](https://github.com/vector-im/element-android/issues/7770))
Other changes
-------------
- [Threads] - added API to fetch threads list from the server instead of building it locally from events ([#5819](https://github.com/vector-im/element-android/issues/5819))
- Add Z-Labs label for rich text editor and migrate to new label naming. ([#7477](https://github.com/vector-im/element-android/issues/7477))
- Crypto database migration tests ([#7645](https://github.com/vector-im/element-android/issues/7645))
- Add tracing Id for to device messages ([#7708](https://github.com/vector-im/element-android/issues/7708))
- Disable nightly popup and add an entry point in the advanced settings instead. ([#7723](https://github.com/vector-im/element-android/issues/7723))
- Save m.local_notification_settings.<device-id> event in account_data ([#7596](https://github.com/vector-im/element-android/issues/7596))
- Update notifications setting when m.local_notification_settings.<device-id> event changes for current device ([#7632](https://github.com/vector-im/element-android/issues/7632))
SDK API changes ⚠️
------------------
- Handle account data removal ([#7740](https://github.com/vector-im/element-android/issues/7740))
Changes in Element 1.5.11 (2022-12-07)
======================================
Bugfixes 🐛
----------
- Fix crash when the network is not available. ([#7725](https://github.com/vector-im/element-android/issues/7725))
Changes in Element v1.5.10 (2022-11-30)
=======================================
Features ✨
----------
- Add setting to allow disabling direct share ([#2725](https://github.com/vector-im/element-android/issues/2725))
- [Device Manager] Toggle IP address visibility ([#7546](https://github.com/vector-im/element-android/issues/7546))
- New implementation of the full screen mode for the Rich Text Editor. ([#7577](https://github.com/vector-im/element-android/issues/7577))
Bugfixes 🐛
----------
- Fix italic text is truncated when bubble mode and markdown is enabled ([#5679](https://github.com/vector-im/element-android/issues/5679))
- Missing translations on "replyTo" messages ([#7555](https://github.com/vector-im/element-android/issues/7555))
- ANR on session start when sending client info is enabled ([#7604](https://github.com/vector-im/element-android/issues/7604))
- Make the plain text mode layout of the RTE more compact. ([#7620](https://github.com/vector-im/element-android/issues/7620))
- Push notification for thread message is now shown correctly when user observes rooms main timeline ([#7634](https://github.com/vector-im/element-android/issues/7634))
- Voice Broadcast - Fix playback stuck in buffering mode ([#7646](https://github.com/vector-im/element-android/issues/7646))
In development 🚧
----------------
- Voice Broadcast - Handle redaction of the state events on the listener and recorder sides ([#7629](https://github.com/vector-im/element-android/issues/7629))
- Voice Broadcast - Update the buffering display in the timeline ([#7655](https://github.com/vector-im/element-android/issues/7655))
- Voice Broadcast - Remove voice messages related to a VB from the room attachments ([#7656](https://github.com/vector-im/element-android/issues/7656))
SDK API changes ⚠️
------------------
- Added support for read receipts in threads. Now user in a room can have multiple read receipts (one per thread + one in main thread + one without threadId) ([#6996](https://github.com/vector-im/element-android/issues/6996))
- Sync Filter now taking in account homeserver capabilities to not pass unsupported parameters.
Sync Filter is now configured by providing SyncFilterBuilder class instance, instead of Filter to identify Filter changes related to homeserver capabilities ([#7626](https://github.com/vector-im/element-android/issues/7626))
Other changes
-------------
- Remove usage of Buildkite. ([#7583](https://github.com/vector-im/element-android/issues/7583))
- Better validation of edits ([#7594](https://github.com/vector-im/element-android/issues/7594))
Changes in Element v1.5.8 (2022-11-17)
======================================
Features ✨
----------
- [Session manager] Multi-session signout ([#7418](https://github.com/vector-im/element-android/issues/7418))
- Rich text editor: add full screen mode. ([#7436](https://github.com/vector-im/element-android/issues/7436))
- [Rich text editor] Add plain text mode ([#7452](https://github.com/vector-im/element-android/issues/7452))
- Move TypingView inside the timeline items. ([#7496](https://github.com/vector-im/element-android/issues/7496))
- Push notifications toggle: align implementation for current session ([#7512](https://github.com/vector-im/element-android/issues/7512))
- Voice messages - Persist the playback position across different screens ([#7582](https://github.com/vector-im/element-android/issues/7582))
Bugfixes 🐛
----------
- [Voice Broadcast] Do not display the recorder view for a live broadcast started from another session ([#7431](https://github.com/vector-im/element-android/issues/7431))
- [Session manager] Hide push notification toggle when there is no server support ([#7457](https://github.com/vector-im/element-android/issues/7457))
- Fix rich text editor textfield not growing to fill parent on full screen. ([#7491](https://github.com/vector-im/element-android/issues/7491))
- Fix duplicated mention pills in some cases ([#7501](https://github.com/vector-im/element-android/issues/7501))
- Voice Broadcast - Fix duplicated voice messages in the internal playlist ([#7502](https://github.com/vector-im/element-android/issues/7502))
- When joining a room, the message composer is displayed once the room is loaded. ([#7509](https://github.com/vector-im/element-android/issues/7509))
- Voice Broadcast - Fix error on voice messages in unencrypted rooms ([#7519](https://github.com/vector-im/element-android/issues/7519))
- Fix description of verified sessions ([#7533](https://github.com/vector-im/element-android/issues/7533))
In development 🚧
----------------
- [Voice Broadcast] Improve timeline items factory and handle bad recording state display ([#7448](https://github.com/vector-im/element-android/issues/7448))
- [Voice Broadcast] Stop recording when opening the room after an app restart ([#7450](https://github.com/vector-im/element-android/issues/7450))
- [Voice Broadcast] Improve playlist fetching and player codebase ([#7478](https://github.com/vector-im/element-android/issues/7478))
- [Voice Broadcast] Display an error dialog if the user fails to start a voice broadcast ([#7485](https://github.com/vector-im/element-android/issues/7485))
- [Voice Broadcast] Add seekbar in listening tile ([#7496](https://github.com/vector-im/element-android/issues/7496))
- [Voice Broadcast] Improve the live indicator icon rendering in the timeline ([#7579](https://github.com/vector-im/element-android/issues/7579))
- Voice Broadcast - Add maximum length ([#7588](https://github.com/vector-im/element-android/issues/7588))
SDK API changes ⚠️
------------------
- [Metrics] Add `SpannableMetricPlugin` to support spans within transactions. ([#7514](https://github.com/vector-im/element-android/issues/7514))
- Fix a bug that caused messages with no formatted text to be quoted as "null". ([#7530](https://github.com/vector-im/element-android/issues/7530))
- If message content has no `formattedBody`, default to `body` when editing. ([#7574](https://github.com/vector-im/element-android/issues/7574))
Changes in Element v1.5.7 (2022-11-07)
======================================
Bugfixes 🐛
----------
- Fix regression when syncing with homeserver < 1.4. ([#7534](https://github.com/vector-im/element-android/issues/7534))
Changes in Element v1.5.6 (2022-11-02)
======================================
Features ✨
----------
- Add new UI for selecting an attachment ([#7429](https://github.com/vector-im/element-android/issues/7429))
- Multi selection in sessions list ([#7396](https://github.com/vector-im/element-android/issues/7396))
Bugfixes 🐛
----------
- New line and Enter hardware key presses deleting existing text in some keyboards. ([#7357](https://github.com/vector-im/element-android/issues/7357))
- Fix share actions using share dialog. ([#7400](https://github.com/vector-im/element-android/issues/7400))
- Fix crash by disabling Flipper on Android API 22 and below - only affects debug version of the application. ([#7428](https://github.com/vector-im/element-android/issues/7428))
In development 🚧
----------------
- [Voice Broadcast] Live listening support ([#7419](https://github.com/vector-im/element-android/issues/7419))
- [Voice Broadcast] Improve rendering in the timeline ([#7421](https://github.com/vector-im/element-android/issues/7421))
- Add logic for sign in with QR code ([#7369](https://github.com/vector-im/element-android/issues/7369))
SDK API changes ⚠️
------------------
- Add MetricPlugin interface to implement metrics in SDK clients. ([#7438](https://github.com/vector-im/element-android/issues/7438))
Other changes
-------------
- Upgrade Jitsi SDK to 6.2.2 and WebRtc to 1.106.1-jitsi-12039821. ([#6195](https://github.com/vector-im/element-android/issues/6195))
- Gets thread notifications from sync response ([#7424](https://github.com/vector-im/element-android/issues/7424))
- Replace org.apache.sanselan:sanselan by org.apache.commons:commons-imaging ([#7454](https://github.com/vector-im/element-android/issues/7454))
Changes in Element v1.5.4 (2022-10-19)
======================================
Features ✨
----------
- Add WYSIWYG editor, under a lab flag. ([#7288](https://github.com/vector-im/element-android/issues/7288))
- New Device management, can be enabled in the labs settings.
- Voice broadcast can be enabled in the labs settings (recording is possible only on Android 10 and up).
Bugfixes 🐛
----------
- Fix wrong mic button direction to cancel on RTL languages ([#5968](https://github.com/vector-im/element-android/issues/5968))
- Handle properly when getUser returns null - prefer using getUserOrDefault ([#7372](https://github.com/vector-im/element-android/issues/7372))
- [Device Management] Long session names not handled well ([#7310](https://github.com/vector-im/element-android/issues/7310))
- Fix editing formatted messages with plain text editor ([#7359](https://github.com/vector-im/element-android/issues/7359))
In development 🚧
----------------
- [Device Management] Save "matrix_client_information" events on login/registration ([#7257](https://github.com/vector-im/element-android/issues/7257))
- [Device management] Add lab flag for the feature ([#7336](https://github.com/vector-im/element-android/issues/7336))
- [Device management] Add lab flag for matrix client info account data event ([#7344](https://github.com/vector-im/element-android/issues/7344))
- [Device Management] Redirect to the new screen everywhere when lab flag is on ([#7374](https://github.com/vector-im/element-android/issues/7374))
- [Device Management] Show correct device type icons ([#7277](https://github.com/vector-im/element-android/issues/7277))
- [Device Management] Render extended device info ([#7294](https://github.com/vector-im/element-android/issues/7294))
- [Device management] Improve the parsing for OS of Desktop/Web sessions ([#7321](https://github.com/vector-im/element-android/issues/7321))
- [Device management] Hide the IP address and last activity date on current session ([#7324](https://github.com/vector-im/element-android/issues/7324))
- [Device management] Update the unknown verification status icon ([#7327](https://github.com/vector-im/element-android/issues/7327))
- [Voice Broadcast] Add the "io.element.voice_broadcast_info" state event with a minimalist timeline widget ([#7273](https://github.com/vector-im/element-android/issues/7273))
- [Voice Broadcast] Aggregate state events in the timeline ([#7283](https://github.com/vector-im/element-android/issues/7283))
- [Voice Broadcast] Record and send non aggregated voice messages to the room ([#7363](https://github.com/vector-im/element-android/issues/7363))
- [Voice Broadcast] Start listening to a voice broadcast ([#7387](https://github.com/vector-im/element-android/issues/7387))
- [Voice Broadcast] Enable the feature (behind a lab flag and only for Android 10 and up) ([#7393](https://github.com/vector-im/element-android/issues/7393))
- [Voice Broadcast] Add additional data in events ([#7397](https://github.com/vector-im/element-android/issues/7397))
- Implements MSC3881: Parses `enabled` and `device_id` fields from updated Pusher API ([#7217](https://github.com/vector-im/element-android/issues/7217))
- Adds pusher toggle setting to device manager v2 ([#7261](https://github.com/vector-im/element-android/issues/7261))
- Implement QR Code Login UI ([#7338](https://github.com/vector-im/element-android/issues/7338))
- Implements client-side of local notification settings event ([#7300](https://github.com/vector-im/element-android/issues/7300))
- Links "Enable Notifications for this session" setting to enabled value in pusher ([#7281](https://github.com/vector-im/element-android/issues/7281))
SDK API changes ⚠️
------------------
- Stop using `original_event` field from `/relations` endpoint ([#7282](https://github.com/vector-im/element-android/issues/7282))
- Add `formattedText` or similar optional parameters in several methods:
* RelationService:
* editTextMessage
* editReply
* replyToMessage
* SendService:
* sendQuotedTextMessage
This allows us to send any HTML formatted text message without needing to rely on automatic Markdown > HTML translation. All these new parameters have a `null` value by default, so previous calls to these API methods remain compatible. ([#7288](https://github.com/vector-im/element-android/issues/7288))
- Add support for `m.login.token` auth during QR code based sign in ([#7358](https://github.com/vector-im/element-android/issues/7358))
- Allow getting the formatted or plain text body of a message for the fun `TimelineEvent.getTextEditableContent()`. ([#7359](https://github.com/vector-im/element-android/issues/7359))
Other changes
-------------
- Refactor TimelineFragment, split it into MessageComposerFragment and VoiceRecorderFragment. ([#7285](https://github.com/vector-im/element-android/issues/7285))
- Dependency to arrow has been removed. Please use `org.matrix.android.sdk.api.util.Optional` instead. ([#7335](https://github.com/vector-im/element-android/issues/7335))
- Update WYSIWYG editor designs. ([#7354](https://github.com/vector-im/element-android/issues/7354))
- Update WYSIWYG library to v0.2.1. ([#7384](https://github.com/vector-im/element-android/issues/7384))
Changes in Element v1.5.2 (2022-10-05)
======================================
Features ✨
----------
- New App Layout is now enabled by default! Go to the Settings > Labs to toggle this ([#7166](https://github.com/vector-im/element-android/issues/7166))
- Render inline images in the timeline ([#351](https://github.com/vector-im/element-android/issues/351))
- Add privacy setting to disable personalized learning by the keyboard ([#6633](https://github.com/vector-im/element-android/issues/6633))
Bugfixes 🐛
----------
- Disable emoji keyboard not applies in reply ([#5029](https://github.com/vector-im/element-android/issues/5029))
- Fix animated images not autoplaying sometimes if only a thumbnail was fetched from the server ([#6215](https://github.com/vector-im/element-android/issues/6215))
- Add Warning shield when a user previously verified rotated their cross signing keys ([#6702](https://github.com/vector-im/element-android/issues/6702))
- Can't verify user when option to send keys to verified devices only is selected ([#6723](https://github.com/vector-im/element-android/issues/6723))
- Add option to only send to verified devices per room (web parity) ([#6725](https://github.com/vector-im/element-android/issues/6725))
- Delete pin code key and the key used for biometrics authentication on logout ([#6906](https://github.com/vector-im/element-android/issues/6906))
- Fix crash on previewing images to upload on Android Pie. ([#7184](https://github.com/vector-im/element-android/issues/7184))
- Fix app restarts in loop on Android 13 on the first run of the app. ([#7224](https://github.com/vector-im/element-android/issues/7224))
In development 🚧
----------------
- [Device Management] Learn more bottom sheets ([#7100](https://github.com/vector-im/element-android/issues/7100))
- [Device management] Verify current session ([#7114](https://github.com/vector-im/element-android/issues/7114))
- [Device management] Verify another session ([#7143](https://github.com/vector-im/element-android/issues/7143))
- [Device management] Rename a session ([#7158](https://github.com/vector-im/element-android/issues/7158))
- [Device Manager] Unverified and inactive sessions list ([#7170](https://github.com/vector-im/element-android/issues/7170))
- [Device management] Sign out a session ([#7190](https://github.com/vector-im/element-android/issues/7190))
- [Device Manager] Parse user agents ([#7247](https://github.com/vector-im/element-android/issues/7247))
- [Voice Broadcast] Add a feature flag with the composer action ([#7258](https://github.com/vector-im/element-android/issues/7258))
Improved Documentation 📚
------------------------
- Draft onboarding documentation of the project at `./docs/_developer_onboarding.md` ([#7126](https://github.com/vector-im/element-android/issues/7126))
SDK API changes ⚠️
------------------
- Allow the sync timeout to be configured (mainly useful for testing) ([#7198](https://github.com/vector-im/element-android/issues/7198))
- Ports SDK instrumentation tests to use suspending functions instead of countdown latches ([#7207](https://github.com/vector-im/element-android/issues/7207))
- [Device Manager] Extend user agent to include device information ([#7209](https://github.com/vector-im/element-android/issues/7209))
Other changes
-------------
- Add support for `/tableflip` command ([#12](https://github.com/vector-im/element-android/issues/12))
- Decreases the size of rounded corners and increases the maximum width of message bubbles to help avoid unnecessary unused space on screen ([#5712](https://github.com/vector-im/element-android/issues/5712))
- Adds screenshot testing tooling ([#5798](https://github.com/vector-im/element-android/issues/5798))
- [AppLayout]: added tracking of new analytics events ([#6508](https://github.com/vector-im/element-android/issues/6508))
- Target API 12 and compile with Android SDK 32. ([#6929](https://github.com/vector-im/element-android/issues/6929))
- Add basic integration of Sentry to capture errors and crashes if user has given consent. ([#7076](https://github.com/vector-im/element-android/issues/7076))
- Add support to `/devtools` command. ([#7126](https://github.com/vector-im/element-android/issues/7126))
- Fix lint warning, and cleanup the code ([#7159](https://github.com/vector-im/element-android/issues/7159))
- Mutualize the pending auth handling ([#7193](https://github.com/vector-im/element-android/issues/7193))
- CI: Prevent modification of translations by developer. ([#7211](https://github.com/vector-im/element-android/issues/7211))
- Fix typo in strings.xml and make sure this is American English. ([#7287](https://github.com/vector-im/element-android/issues/7287))
Changes in Element v1.5.1 (2022-09-28)
======================================
Security ⚠️
----------
This update provides important security fixes, update now.
Ref: CVE-2022-39246 CVE-2022-39248
Changes in Element v1.5.0 (2022-09-23)
======================================
Features ✨
----------
- Deferred DMs - Enable and move the feature to labs settings ([#7180](https://github.com/vector-im/element-android/issues/7180))
Bugfixes 🐛
----------
- Fix text margin in QR code view when no display name is set ([#5424](https://github.com/vector-im/element-android/issues/5424))
- [App Layout] Recents carousel now scrolled to first position when new item added to or moved to this position ([#6776](https://github.com/vector-im/element-android/issues/6776))
- Fixed problem when room list's scroll did jump after rooms placeholders were replaced with rooms summary items ([#7079](https://github.com/vector-im/element-android/issues/7079))
- Fixes crash when quickly double clicking FABs in the new app layout ([#7102](https://github.com/vector-im/element-android/issues/7102))
- Fixes space list and new chat bottom sheets showing too small in New App Layout (especially evident in landscape) ([#7103](https://github.com/vector-im/element-android/issues/7103))
- [App Layout] Room leaving prompt dialog now waits user to confirm leaving before do so ([#7122](https://github.com/vector-im/element-android/issues/7122))
- Fix empty verification bottom sheet. ([#7130](https://github.com/vector-im/element-android/issues/7130))
- [New Layout] Fixes new chat dialog not getting dismissed after selecting its actions ([#7132](https://github.com/vector-im/element-android/issues/7132))
- Fixes Room List not getting updated when fragment is not in focus ([#7186](https://github.com/vector-im/element-android/issues/7186))
In development 🚧
----------------
- Create DM room only on first message - Add a spinner when sending the first message ([#6970](https://github.com/vector-im/element-android/issues/6970))
- [Device Manager] Filter Other Sessions ([#7045](https://github.com/vector-im/element-android/issues/7045))
- [Device management] Session details screen ([#7077](https://github.com/vector-im/element-android/issues/7077))
- Create DM room only on first message - Fix glitch in the room list ([#7121](https://github.com/vector-im/element-android/issues/7121))
- Create DM room only on first message - Handle the local rooms within the new AppLayout ([#7153](https://github.com/vector-im/element-android/issues/7153))
Other changes
-------------
- [Modules] Lifts the application variants to the app module ([#6779](https://github.com/vector-im/element-android/issues/6779))
- Ensure that we do not expect all the Event fields when requesting `rooms/{roomId}/hierarchy` endpoint. ([#7035](https://github.com/vector-im/element-android/issues/7035))
- Move some GitHub actions to buildjet runners, and remove the second attempt to run integration tests. ([#7108](https://github.com/vector-im/element-android/issues/7108))
- Exclude legacy android support annotation library ([#7140](https://github.com/vector-im/element-android/issues/7140))
- Pulling no longer hosted im.dlg:android-dialer directly into the repository and removing legacy support library usages ([#7142](https://github.com/vector-im/element-android/issues/7142))
- Fixing build cache misses when compiling the vector module ([#7157](https://github.com/vector-im/element-android/issues/7157))
Changes in Element v1.4.36 (2022-09-10)
=======================================
New App Layout can be enabled in the Labs settings. Please give it a try!
Features ✨
----------
- Adds New App Layout into Labs ([#7038](https://github.com/vector-im/element-android/issues/7038))
- Try to detect devices that lack Opus encoder support, use bundled libopus library for those. ([#7010](https://github.com/vector-im/element-android/issues/7010))
- Suggest @room when @channel, @everyone, or @here is typed in composer ([#6529](https://github.com/vector-im/element-android/issues/6529))
Bugfixes 🐛
----------
- Fix long incremental sync. ([#6917](https://github.com/vector-im/element-android/issues/6917))
- Fix push with FCM ([#7068](https://github.com/vector-im/element-android/issues/7068))
- FTUE - Fixes optional email registration step always being mandatory ([#6969](https://github.com/vector-im/element-android/issues/6969))
- Fixes /addToSpace and /joinSpace commands showing invalid syntax warnings ([#6844](https://github.com/vector-im/element-android/issues/6844))
- Fix low occurrence crashes. ([#6967](https://github.com/vector-im/element-android/issues/6967))
- Fix crash when opening an unknown room ([#6978](https://github.com/vector-im/element-android/issues/6978))
- Fix crash on PIN code settings screen. ([#6979](https://github.com/vector-im/element-android/issues/6979))
- Fix autoplayed animated stickers ([#6982](https://github.com/vector-im/element-android/issues/6982))
- Catch race condition crash in voice recording ([#6989](https://github.com/vector-im/element-android/issues/6989))
- Fix invite to room when in a space buttons not working. ([#7054](https://github.com/vector-im/element-android/issues/7054))
In development 🚧
----------------
- Create DM room only on first message - Create the DM and navigate to the new room after sending an event ([#5525](https://github.com/vector-im/element-android/issues/5525))
- [App Layout] New empty states for home screen ([#6835](https://github.com/vector-im/element-android/issues/6835))
- [App Layout] Bottom navigation tabs are removed for new home screen ([#6565](https://github.com/vector-im/element-android/issues/6565))
- [App Layout] fixed space switching dialog measured with wrong height sometimes ([#6750](https://github.com/vector-im/element-android/issues/6750))
- [App Layout] Fabs doesn't go off screen anymore ([#6765](https://github.com/vector-im/element-android/issues/6765))
- [New Layout] Adds back navigation through spaces ([#6877](https://github.com/vector-im/element-android/issues/6877))
- [App Layout] new room invites screen ([#6889](https://github.com/vector-im/element-android/issues/6889))
- [App Layout] - Invites now show empty screen after you reject last invite ([#6876](https://github.com/vector-im/element-android/issues/6876))
- [App Layout] - space switcher now has empty state ([#6754](https://github.com/vector-im/element-android/issues/6754))
- [App Layout] - Improves Developer Mode Debug Button UX and adds it to New App Layout ([#6871](https://github.com/vector-im/element-android/issues/6871))
- [New Layout] Changes space sheet to accordion-style with expandable subspaces ([#6907](https://github.com/vector-im/element-android/issues/6907))
- [New Layout] Adds space invites ([#6924](https://github.com/vector-im/element-android/issues/6924))
- [App Layout] fixed invites count badge bottom margin on a home screen ([#6947](https://github.com/vector-im/element-android/issues/6947))
- [New Layout] Improves talkback accessibility ([#7016](https://github.com/vector-im/element-android/issues/7016))
- [New Layout] Changes space icon in fab and in release notes screen ([#7039](https://github.com/vector-im/element-android/issues/7039))
- [New Layout] Adds header to spaces bottom sheet ([#7040](https://github.com/vector-im/element-android/issues/7040))
- [App Layout] New App Layout is enabled by default (Edit: has to be enabled in Labs) ([#6958](https://github.com/vector-im/element-android/issues/6958))
- [App Layout] Obsolete settings are not shown when App Layout flag is enabled ([#6646](https://github.com/vector-im/element-android/issues/6646))
- [Devices Management] Session overview screen ([#6961](https://github.com/vector-im/element-android/issues/6961))
- [Devices Management] Refactor some code to improve testability ([#7043](https://github.com/vector-im/element-android/issues/7043))
- [Device Manager] Current Session Section ([#6902](https://github.com/vector-im/element-android/issues/6902))
- [Device Manager] Other Sessions Section ([#6945](https://github.com/vector-im/element-android/issues/6945))
- [Device Manager] Render Security Recommendations ([#6964](https://github.com/vector-im/element-android/issues/6964))
Improved Documentation 📚
------------------------
- Clarify that setting up a FCM Rewrite Proxy is not necessary for use of the UnifiedPush FCM distributor. ([#6727](https://github.com/vector-im/element-android/issues/6727))
Other changes
-------------
- Increase sticker size ([#6982](https://github.com/vector-im/element-android/issues/6982))
- Focus input field when editing homeserver address to speed up login and registration. ([#6926](https://github.com/vector-im/element-android/issues/6926))
- Log basic Http information in production. ([#6925](https://github.com/vector-im/element-android/issues/6925))
- Converts the vector module to a library with a parent vector-app application module ([#6407](https://github.com/vector-im/element-android/issues/6407))
- Creates a dedicated strings module ([#3955](https://github.com/vector-im/element-android/issues/3955))
- Remove FragmentModule and the Fragment factory. No need to Inject the constructor on your Fragment, just add @AndroidEntryPoint annotation and @Inject class members. ([#6894](https://github.com/vector-im/element-android/issues/6894))
- Small refactor of UnifiedPushHelper ([#6936](https://github.com/vector-im/element-android/issues/6936))
- CI: only run sonarqube task when token is known ([#7057](https://github.com/vector-im/element-android/issues/7057))
Changes in Element v1.4.34 (2022-08-23)
=======================================
Features ✨
----------
- [Notification] - Handle creation of notification for live location and poll start ([#6746](https://github.com/vector-im/element-android/issues/6746))
Bugfixes 🐛
----------
- Fixes onboarding requiring matrix.org to be accessible on the first step, the server can now be manually changed ([#6718](https://github.com/vector-im/element-android/issues/6718))
- Fixing sign in/up for homeservers that rely on the SSO fallback url ([#6827](https://github.com/vector-im/element-android/issues/6827))
- Fixes uncaught exceptions in the SyncWorker to cause the worker to become stuck in the failure state ([#6836](https://github.com/vector-im/element-android/issues/6836))
- Fixes onboarding captcha crashing when no WebView is available by showing an error with information instead ([#6855](https://github.com/vector-im/element-android/issues/6855))
- Removes ability to continue registration after the app has been destroyed, fixes the next steps crashing due to missing information from the previous steps ([#6860](https://github.com/vector-im/element-android/issues/6860))
- Fixes crash when exiting the login or registration entry screens whilst they're loading ([#6861](https://github.com/vector-im/element-android/issues/6861))
- Fixes server selection being unable to trust certificates ([#6864](https://github.com/vector-im/element-android/issues/6864))
- Ensure SyncThread is started when the app is launched after a Push has been received. ([#6884](https://github.com/vector-im/element-android/issues/6884))
- Fixes missing firebase notifications after logging in when UnifiedPush distributor is installed ([#6891](https://github.com/vector-im/element-android/issues/6891))
In development 🚧
----------------
- Create DM room only on first message - Trigger the flow when the "Direct Message" action is selected from the room member details screen ([#5525](https://github.com/vector-im/element-android/issues/5525))
- added filter tabs for new App layout's Home screen ([#6505](https://github.com/vector-im/element-android/issues/6505))
- [App Layout] added dialog to configure app layout ([#6506](https://github.com/vector-im/element-android/issues/6506))
- Adds space list bottom sheet for new app layout ([#6749](https://github.com/vector-im/element-android/issues/6749))
- [App Layout] Dialpad moved from bottom navigation tab to a separate activity accessed via home screen context menu ([#6787](https://github.com/vector-im/element-android/issues/6787))
- Makes toolbar switch title based on space in New App Layout ([#6795](https://github.com/vector-im/element-android/issues/6795))
- [Devices management] Add a feature flag and empty screen for future new layout ([#6798](https://github.com/vector-im/element-android/issues/6798))
- Adds new chat bottom sheet as the click action of the main FAB in the new app layout ([#6801](https://github.com/vector-im/element-android/issues/6801))
- [Devices management] Other sessions section in new layout ([#6806](https://github.com/vector-im/element-android/issues/6806))
- [New Layout] Adds space settings accessible through clicking the toolbar ([#6859](https://github.com/vector-im/element-android/issues/6859))
- Adds New App Layout FABs (hidden behind feature flag) ([#6693](https://github.com/vector-im/element-android/issues/6693))
SDK API changes ⚠️
------------------
- Rename `DebugService.logDbUsageInfo` (resp. `Session.logDbUsageInfo`) to `DebugService.getDbUsageInfo` (resp. `Session.getDbUsageInfo`) and return a String instead of logging. The caller may want to log the String. ([#6884](https://github.com/vector-im/element-android/issues/6884))
Other changes
-------------
- Removes the Login2 proof of concept - replaced by the FTUE changes ([#5974](https://github.com/vector-im/element-android/issues/5974))
- Enable auto-capitalization for Room creation Title field ([#6645](https://github.com/vector-im/element-android/issues/6645))
- Decouples the variant logic from the vector module ([#6783](https://github.com/vector-im/element-android/issues/6783))
- Add a developer setting to enable LeakCanary at runtime ([#6786](https://github.com/vector-im/element-android/issues/6786))
- [Create Room] Reduce some boilerplate with room state event contents ([#6799](https://github.com/vector-im/element-android/issues/6799))
- [Call] Memory leak after a call ([#6808](https://github.com/vector-im/element-android/issues/6808))
- Fix some string template ([#6843](https://github.com/vector-im/element-android/issues/6843))
Changes in Element v1.4.32 (2022-08-10)
=======================================
Features ✨
----------
- [Location Share] Render fallback UI when map fails to load ([#6711](https://github.com/vector-im/element-android/issues/6711))
Bugfixes 🐛
----------
- Fix message content sometimes appearing in the log ([#6706](https://github.com/vector-im/element-android/issues/6706))
- Disable 'Enable biometrics' option if there are not biometric authenticators enrolled. ([#6713](https://github.com/vector-im/element-android/issues/6713))
- Fix crash when biometric key is used when coming back to foreground and KeyStore reports that the device is still locked. ([#6768](https://github.com/vector-im/element-android/issues/6768))
- Catch all exceptions on lockscreen system key migrations. ([#6769](https://github.com/vector-im/element-android/issues/6769))
- Fixes crash when entering non ascii characters during account creation ([#6735](https://github.com/vector-im/element-android/issues/6735))
- Fixes onboarding login/account creation errors showing after navigation ([#6737](https://github.com/vector-im/element-android/issues/6737))
- [Location sharing] Invisible text on map symbol ([#6687](https://github.com/vector-im/element-android/issues/6687))
In development 🚧
----------------
- Adds new app layout toolbar ([#6655](https://github.com/vector-im/element-android/issues/6655))
Other changes
-------------
- [Modularization] Provides abstraction to avoid direct usages of BuildConfig ([#6406](https://github.com/vector-im/element-android/issues/6406))
- Refactors SpaceStateHandler (previously AppStateHandler) and adds unit tests for it ([#6598](https://github.com/vector-im/element-android/issues/6598))
- Setup Danger to the project ([#6637](https://github.com/vector-im/element-android/issues/6637))
- [Location Share] Open maximized map on tapping on live sharing notification ([#6642](https://github.com/vector-im/element-android/issues/6642))
- [Location sharing] Align naming of components for live location feature ([#6647](https://github.com/vector-im/element-android/issues/6647))
- [Location share] Update minimum sending period to 5 seconds for a live ([#6653](https://github.com/vector-im/element-android/issues/6653))
- [Location sharing] - Fix the memory leaks ([#6674](https://github.com/vector-im/element-android/issues/6674))
- [Timeline] Memory leak in audio message playback tracker ([#6678](https://github.com/vector-im/element-android/issues/6678))
- [FTUE] Memory leak on FtueAuthSplashCarouselFragment ([#6680](https://github.com/vector-im/element-android/issues/6680))
- Link directly to DCO docs from danger message. ([#6739](https://github.com/vector-im/element-android/issues/6739))
Changes in Element v1.4.31 (2022-08-01)
=======================================
Bugfixes 🐛
----------
- Fixes crash when returning to the app after backgrounding ([#6709](https://github.com/vector-im/element-android/issues/6709))
- Fix message content sometimes appearing in the log ([#6706](https://github.com/vector-im/element-android/issues/6706))
Changes in Element v1.4.30 (2022-07-29)
=======================================
Features ✨
----------
- [FTUE] - Enable improved login and register onboarding flows ([#2585](https://github.com/vector-im/element-android/issues/2585))
- Adds settings screen to change app font scale or enable using system setting ([#5687](https://github.com/vector-im/element-android/issues/5687))
- [Location sharing] - Delete action on a live message ([#6437](https://github.com/vector-im/element-android/issues/6437))
- [Timeline] - Collapse redacted events ([#6487](https://github.com/vector-im/element-android/issues/6487))
- Improve lock screen implementation with extra security measures ([#6522](https://github.com/vector-im/element-android/issues/6522))
- Move initialization of the Session to a background thread. MainActivity is restoring the session now, instead of VectorApplication. Useful when for instance a long migration of a database is required. ([#6548](https://github.com/vector-im/element-android/issues/6548))
- Share location with other apps ([#6567](https://github.com/vector-im/element-android/issues/6567))
- Support element call widget ([#6616](https://github.com/vector-im/element-android/issues/6616))
- [FTUE] Updates FTUE registration to include username availability check and update copy ([#6546](https://github.com/vector-im/element-android/issues/6546))
- [FTUE] - Allows the email address to be changed during the verification process ([#6622](https://github.com/vector-im/element-android/issues/6622))
- [FTUE] Updates the copy within the FTUE onboarding ([#6547](https://github.com/vector-im/element-android/issues/6547))
- [FTUE] Test session feedback ([#6620](https://github.com/vector-im/element-android/issues/6620))
- [FTUE] - Improved reset password error message ([#6621](https://github.com/vector-im/element-android/issues/6621))
Bugfixes 🐛
----------
- Fixes wrong voice message being displayed and played on the timeline. ([#6213](https://github.com/vector-im/element-android/issues/6213))
- Fixes the room list not taking into account the Show all rooms in Home preference ([#6665](https://github.com/vector-im/element-android/issues/6665))
- Stop using unstable names for withheld codes ([#5115](https://github.com/vector-im/element-android/issues/5115))
- Fixes room not being in space after upgrade ([#6200](https://github.com/vector-im/element-android/issues/6200))
- Fixed issues with reporting sync state events from different threads ([#6341](https://github.com/vector-im/element-android/issues/6341))
- Display specific message when verification QR code is malformed ([#6395](https://github.com/vector-im/element-android/issues/6395))
- When there is no way to verify a device (no 4S nor other device) propose to reset verification keys ([#6466](https://github.com/vector-im/element-android/issues/6466))
- Unwedging could cause the SDK to force creating a new olm session every hour ([#6534](https://github.com/vector-im/element-android/issues/6534))
- [Location Share] - Wrong room live location status bar visibility in timeline ([#6537](https://github.com/vector-im/element-android/issues/6537))
- Fix infinite loading when opening a DM when the current room is the same DM. ([#6549](https://github.com/vector-im/element-android/issues/6549))
- Do not log the live location of the user ([#6579](https://github.com/vector-im/element-android/issues/6579))
- Fix backup saving several times the same keys ([#6585](https://github.com/vector-im/element-android/issues/6585))
- Check user power level before sharing live location ([#6587](https://github.com/vector-im/element-android/issues/6587))
- [Location Share] - Live is considered as ended while still active ([#6596](https://github.com/vector-im/element-android/issues/6596))
- Put EC permission shortcuts behind labs flag (PSG-630) ([#6634](https://github.com/vector-im/element-android/issues/6634))
- ObjectAnimators are not canceled in TypingMessageDotsView ([#6663](https://github.com/vector-im/element-android/issues/6663))
SDK API changes ⚠️
------------------
- Communities/Groups are removed completely ([#5733](https://github.com/vector-im/element-android/issues/5733))
- SDK - The SpaceFilter is query parameter is no longer nullable, use SpaceFilter.NoFilter instead ([#6666](https://github.com/vector-im/element-android/issues/6666))
Other changes
-------------
- Nightly build publication on Firebase ([#6478](https://github.com/vector-im/element-android/issues/6478))
- Communities/Groups are removed completely ([#5733](https://github.com/vector-im/element-android/issues/5733))
- Improves performance on search screen by replacing flattenParents with directParentName in RoomSummary ([#6314](https://github.com/vector-im/element-android/issues/6314))
- Log durations of DB migration and migration steps. ([#6538](https://github.com/vector-im/element-android/issues/6538))
- [Location Share] - Standardise "Stop" texts for live ([#6541](https://github.com/vector-im/element-android/issues/6541))
- Adds NewAppLayoutEnabled feature flag ([#6584](https://github.com/vector-im/element-android/issues/6584))
- [Location sharing] - Small improvements of UI for live ([#6607](https://github.com/vector-im/element-android/issues/6607))
- Live Location Sharing - Reset zoom level while focusing a user ([#6609](https://github.com/vector-im/element-android/issues/6609))
- Fix a typo in the terms and conditions step during registration. ([#6612](https://github.com/vector-im/element-android/issues/6612))
- [Location sharing] - OnTap on the top live status bar, display the expanded map view ([#6625](https://github.com/vector-im/element-android/issues/6625))
- [Location Share] - Expanded map state when no more live location shares ([#6635](https://github.com/vector-im/element-android/issues/6635))
Changes in Element v1.4.28 (2022-07-13)
=======================================
Features ✨
----------
- Improve user experience when he is first invited to a room. Users will be able to decrypt and view previous messages ([#5853](https://github.com/vector-im/element-android/issues/5853))
- [Location sharing] - Reply action on a live message ([#6401](https://github.com/vector-im/element-android/issues/6401))
- Show a loader if all the Room Members are not yet loaded. ([#6413](https://github.com/vector-im/element-android/issues/6413))
Bugfixes 🐛
----------
- Fixes numbered lists always starting from 1 ([#4777](https://github.com/vector-im/element-android/issues/4777))
- Adds LoginType to SessionParams to fix soft logout form not showing for SSO and Password type ([#5398](https://github.com/vector-im/element-android/issues/5398))
- Use stable endpoint for alias management instead of MSC2432. Contributed by Nico. ([#6288](https://github.com/vector-im/element-android/issues/6288))
- [Poll] Fixes visible and wrong votes in closed poll after removing 2 previous polls ([#6430](https://github.com/vector-im/element-android/issues/6430))
- Fix HTML entities being displayed in messages ([#6442](https://github.com/vector-im/element-android/issues/6442))
- Gallery picker can pick external images ([#6450](https://github.com/vector-im/element-android/issues/6450))
- Fixes crash when sharing plain text, such as a url ([#6451](https://github.com/vector-im/element-android/issues/6451))
- Fix crashes on Timeline [Thread] due to range validation ([#6461](https://github.com/vector-im/element-android/issues/6461))
- Fix crashes when opening Thread ([#6463](https://github.com/vector-im/element-android/issues/6463))
- Fix ConcurrentModificationException on BackgroundDetectionObserver ([#6469](https://github.com/vector-im/element-android/issues/6469))
- Fixes inconsistency with rooms within spaces showing or disappearing from home ([#6510](https://github.com/vector-im/element-android/issues/6510))
In development 🚧
----------------
- FTUE - Adds support for resetting the password during the FTUE onboarding journey ([#5284](https://github.com/vector-im/element-android/issues/5284))
- Create DM room only on first message - Design implementation & debug feature flag ([#5525](https://github.com/vector-im/element-android/issues/5525))
Other changes
-------------
- Replacing Epoxy annotation layout id references with getDefaultLayoutId ([#6389](https://github.com/vector-im/element-android/issues/6389))
- Ensure `RealmList<T>.clearWith()` extension is correctly used. ([#6392](https://github.com/vector-im/element-android/issues/6392))
- [Poll] - Add a description under undisclosed poll when not ended ([#6423](https://github.com/vector-im/element-android/issues/6423))
- Add `android:hasFragileUserData="true"` in the manifest ([#6429](https://github.com/vector-im/element-android/issues/6429))
- Add code check to prevent modification of frozen class ([#6434](https://github.com/vector-im/element-android/issues/6434))
- Let your Activity or Fragment implement `VectorMenuProvider` if they provide a menu. ([#6436](https://github.com/vector-im/element-android/issues/6436))
- Rename Android Service to use `AndroidService` suffix ([#6458](https://github.com/vector-im/element-android/issues/6458))
Changes in Element v1.4.27 (2022-07-06)
=======================================
Bugfixes 🐛
----------
- Fixes crash when sharing plain text, such as a url ([#6451](https://github.com/vector-im/element-android/issues/6451))
- Fix crashes on Timeline [Thread] due to range validation ([#6461](https://github.com/vector-im/element-android/issues/6461))
- Fix crashes when opening Thread ([#6463](https://github.com/vector-im/element-android/issues/6463))
- Fix ConcurrentModificationException on BackgroundDetectionObserver ([#6469](https://github.com/vector-im/element-android/issues/6469))
Changes in Element v1.4.26 (2022-06-30)
=======================================

View file

@ -1,10 +1,43 @@
# Contributing code to Matrix
# Contributing to Element Android
<!--- TOC -->
* [Contributing code to Matrix](#contributing-code-to-matrix)
* [Android Studio settings](#android-studio-settings)
* [Template](#template)
* [Compilation](#compilation)
* [I want to help translating Element](#i-want-to-help-translating-element)
* [I want to submit a PR to fix an issue](#i-want-to-submit-a-pr-to-fix-an-issue)
* [Kotlin](#kotlin)
* [Changelog](#changelog)
* [Code quality](#code-quality)
* [Internal tool](#internal-tool)
* [ktlint](#ktlint)
* [knit](#knit)
* [lint](#lint)
* [Unit tests](#unit-tests)
* [Tests](#tests)
* [Internationalisation](#internationalisation)
* [Adding new string](#adding-new-string)
* [Plurals](#plurals)
* [Editing existing strings](#editing-existing-strings)
* [Removing existing strings](#removing-existing-strings)
* [Renaming string ids](#renaming-string-ids)
* [Reordering strings](#reordering-strings)
* [Accessibility](#accessibility)
* [Layout](#layout)
* [Authors](#authors)
* [Thanks](#thanks)
<!--- END -->
## Contributing code to Matrix
Please read https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md
Element Android support can be found in this room: [![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org).
# Specific rules for Matrix Android projects
The rest of the document contains specific rules for Matrix Android projects
## Android Studio settings
@ -94,6 +127,23 @@ Note that you can run
For ktlint to fix some detected errors for you (you still have to check and commit the fix of course)
#### knit
[knit](https://github.com/Kotlin/kotlinx-knit) is a tool which checks markdown files on the project. Also it generates/updates the table of content (toc) of the markdown files.
So everytime the toc should be updated, just run
<pre>
./gradlew knit
</pre>
and commit the changes.
The CI will check that markdown files are up to date by running
<pre>
./gradlew knitCheck
</pre>
#### lint
<pre>
@ -120,17 +170,21 @@ You should consider adding Unit tests with your PR, and also integration tests (
Translations are handled using an external tool: [Weblate](https://translate.element.io/projects/element-android/)
As a general rule, please never edit or add or remove translations to the project in a Pull Request. It can lead to merge conflict if the translations are also modified in Weblate side.
**As a general rule, please never edit or add or remove translations to the project in a Pull Request**. It can lead to merge conflict if the translations are also modified in Weblate side. Pull Request containing change(s) on the translation files cannot be merged.
#### Adding new string
When adding new string resources, please only add new entries in the file `value/strings.xml`. Translations will be added later by the community of translators using Weblate.
When adding new string resources, please only add new entries in the file `values/strings.xml` ([this file](./library/ui-strings/src/main/res/values/strings.xml)). Translations will be added later by the community of translators using Weblate.
The file `value/strings.xml` must only contain American English (U. S. English) values, as this is the default language of the Android operating system. So for instance, please use "color" instead of "colour". Element Android will still use the language set on the system by the user, like any other Android applications which provide translations. The system language can be any other English language variants, or any other languages. Note that this is also possible to override the system language using the Element Android in-app language settings.
The file `values/strings.xml` must only contain American English (U. S. English) values, as this is the default language of the Android operating system. So for instance, please use "color" instead of "colour". Element Android will still use the language set on the system by the user, like any other Android applications which provide translations. The system language can be any other English language variants, or any other languages. Note that this is also possible to override the system language using the Element Android in-app language settings.
New strings can be added anywhere in the file `value/strings.xml`, not necessarily at the end of the file. Generally, it's even better to add the new strings in some dedicated section per feature, and not at the end of the file, to avoid merge conflict between 2 PR adding strings at the end of the same file.
New strings can be added anywhere in the file `values/strings.xml`, not necessarily at the end of the file. Generally, it's even better to add the new strings in some dedicated section per feature, and not at the end of the file, to avoid merge conflict between 2 PR adding strings at the end of the same file.
Do not hesitate to use plurals when appropriate.
##### Plurals
Please use `plurals` resources when appropriate, and note that some languages have specific rules for `plurals`, so even if the string will always be at the plural form for English, please always create a `plurals` resource.
Specific plural forms can be found [here](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html).
#### Editing existing strings
@ -150,6 +204,23 @@ And add `tools:ignore="UnusedResources"` to the string, to let lint ignore that
The string will be removed during the next sync with Weblate.
#### Renaming string ids
This is possible to rename ids of the String resources, but since translation files cannot be edited, add TODO in the main strings.xml file above the strings you want to rename.
```xml
<!-- TODO Rename id to put_new_id_here -->
<string name="current_id">Hello Matrix world!</string>
```
The string id(s) will be renamed during the next Weblate sync.
#### Reordering strings
To group strings per feature, or for any other reasons, it is possible to reorder string resources, but only in the [main strings.xml file](./library/ui-strings/src/main/res/values/strings.xml). ). We do not mind about ordering in the translation files, and anyway this is forbidden to edit manually the translation files.
It is also possible to add empty lines between string resources, and to add XML comments. Please note that the XML comment just above a String resource will also appear on Weblate and be visible to the translators.
### Accessibility
Please consider accessibility as an important point. As a minimum requirement, in layout XML files please use attributes such as `android:contentDescription` and `android:importantForAccessibility`, and test with a screen reader if it's working well. You can add new string resources, dedicated to accessibility, in this case, please prefix theirs id with `a11y_`.

View file

@ -1,3 +1,4 @@
source "https://rubygems.org"
gem "fastlane"
gem 'danger'

View file

@ -1,50 +1,72 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.3)
CFPropertyList (3.0.5)
rexml
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.1.1)
aws-partitions (1.479.0)
aws-sdk-core (3.117.0)
aws-eventstream (1.2.0)
aws-partitions (1.619.0)
aws-sdk-core (3.132.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.44.0)
aws-sdk-core (~> 3, >= 3.112.0)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.58.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.96.1)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.4)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
claide (1.1.0)
claide-plugins (0.9.2)
cork
nap
open4 (~> 1.3)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
cork (0.3.0)
colored2 (~> 3.1)
danger (8.6.1)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (>= 0.9.0, < 2.0)
faraday-http-cache (~> 2.0)
git (~> 1.7)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (~> 4.7)
terminal-table (>= 1, < 4)
declarative (0.0.20)
digest-crc (0.6.3)
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.2.2)
excon (0.85.0)
faraday (1.5.1)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.92.4)
faraday (1.10.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
multipart-post (>= 1.2, < 3)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
@ -52,16 +74,22 @@ GEM
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-http-cache (2.4.1)
faraday (>= 0.8)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday_middleware (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.4)
fastlane (2.187.0)
fastimage (2.2.6)
fastlane (2.209.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
aws-sdk-s3 (~> 1.0)
babosa (>= 1.0.3, < 2.0.0)
@ -76,7 +104,7 @@ GEM
faraday_middleware (~> 1.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-apis-androidpublisher_v3 (~> 0.1)
google-apis-androidpublisher_v3 (~> 0.3)
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
@ -85,6 +113,7 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (~> 2.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
@ -98,9 +127,12 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.8.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.0)
git (1.13.0)
addressable (~> 2.8)
rchardet (~> 1.8)
google-apis-androidpublisher_v3 (0.25.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-core (0.7.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@ -109,52 +141,64 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
google-apis-iamcredentials_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.5.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-iamcredentials_v1 (0.13.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-playcustomapp_v1 (0.10.0)
google-apis-core (>= 0.7, < 2.a)
google-apis-storage_v1 (0.17.0)
google-apis-core (>= 0.7, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.34.1)
addressable (~> 2.5)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.2.0)
google-cloud-storage (1.38.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.17.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (0.16.2)
faraday (>= 0.17.3, < 2.0)
googleauth (1.2.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.14)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.4)
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.4.0)
json (2.5.1)
jwt (2.2.3)
jmespath (1.6.1)
json (2.6.2)
jwt (2.4.1)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
memoist (0.16.2)
mini_magick (4.11.0)
mini_mime (1.1.0)
mini_mime (1.1.2)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1)
os (1.1.1)
no_proxy_fix (0.1.2)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (4.0.6)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.1.1)
rchardet (1.8.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
@ -163,10 +207,13 @@ GEM
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
security (0.1.3)
signet (0.15.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
signet (0.17.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.8)
@ -175,7 +222,7 @@ GEM
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
trailblazer-option (0.1.1)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
@ -183,11 +230,11 @@ GEM
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.20.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
@ -200,9 +247,12 @@ GEM
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
universal-darwin-21
x86_64-darwin-20
x86_64-linux
DEPENDENCIES
danger
fastlane
BUNDLED WITH

View file

@ -1,4 +1,4 @@
[![Buildkite](https://badge.buildkite.com/ad0065c1b70f557cd3b1d3d68f9c2154010f83c4d6f71706a9.svg?branch=develop)](https://buildkite.com/matrix-dot-org/element-android/builds?branch=develop)
[![Latest build](https://github.com/vector-im/element-android/actions/workflows/build.yml/badge.svg?query=branch%3Adevelop)](https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%3Adevelop)
[![Weblate](https://translate.element.io/widgets/element-android/-/svg-badge.svg)](https://translate.element.io/engage/element-android/?utm_source=widget)
[![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vector-im_element-android&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
@ -14,7 +14,7 @@ It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-androi
[<img src="resources/img/google-play-badge.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.app)
[<img src="resources/img/f-droid-badge.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/app/im.vector.app)
Nightly build: [![Buildkite](https://badge.buildkite.com/ad0065c1b70f557cd3b1d3d68f9c2154010f83c4d6f71706a9.svg?branch=develop)](https://buildkite.com/matrix-dot-org/element-android/builds?branch=develop) Nightly test status: [![allScreensTest](https://github.com/vector-im/element-android/actions/workflows/nightly.yml/badge.svg)](https://github.com/vector-im/element-android/actions/workflows/nightly.yml)
Build of develop branch: [![GitHub Action](https://github.com/vector-im/element-android/actions/workflows/build.yml/badge.svg?query=branch%3Adevelop)](https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%3Adevelop) Nightly test status: [![allScreensTest](https://github.com/vector-im/element-android/actions/workflows/nightly.yml/badge.svg)](https://github.com/vector-im/element-android/actions/workflows/nightly.yml)
# New Android SDK
@ -40,14 +40,16 @@ If you would like to receive releases more quickly (bearing in mind that they ma
1. [Sign up to receive beta releases](https://play.google.com/apps/testing/im.vector.app) via the Google Play Store.
2. Install a [release APK](https://github.com/vector-im/element-android/releases) directly - download the relevant .apk file and allow installing from untrusted sources in your device settings. Note: these releases are the Google Play version, which depend on some Google services. If you prefer to avoid that, try the latest dev builds, and choose the F-Droid version.
3. If you're really brave, install the [very latest dev build](https://buildkite.com/matrix-dot-org/element-android/builds/latest?branch=develop&state=passed) - click on *Assemble (GPlay or FDroid) Debug version* then on *Artifacts*.
3. If you're really brave, install the [very latest dev build](https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%3Adevelop) - pick a build, then click on `Summary` to download the APKs from there: `vector-Fdroid-debug` and `vector-Gplay-debug` contains the APK for the desired store. Each file contains 5 APKs. 4 APKs for every supported specific architecture of device. In doubt you can install the `universal` APK.
## Contributing
Please refer to [CONTRIBUTING.md](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects!
Please refer to [CONTRIBUTING.md](./CONTRIBUTING.md) if you want to contribute on Matrix Android projects!
Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#element-android:matrix.org).
Also [this documentation](./docs/_developer_onboarding.md) can hopefully help developers to start working on the project.
## Triaging issues
Issues are triaged by community members and the Android App Team, following the [triage process](https://github.com/vector-im/element-meta/wiki/Triage-process).

5
SECURITY.md Normal file
View file

@ -0,0 +1,5 @@
# Reporting a Vulnerability
**If you've found a security vulnerability, please report it to security@matrix.org**
For more information on our security disclosure policy, visit https://www.matrix.org/security-disclosure-policy/

View file

@ -24,13 +24,16 @@ buildscript {
classpath libs.gradle.gradlePlugin
classpath libs.gradle.kotlinPlugin
classpath libs.gradle.hiltPlugin
classpath 'com.google.gms:google-services:4.3.13'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
classpath "com.likethesalad.android:stem-plugin:2.1.1"
classpath 'org.owasp:dependency-check-gradle:7.1.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.0"
classpath 'com.google.firebase:firebase-appdistribution-gradle:3.2.0'
classpath 'com.google.gms:google-services:4.3.15'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6'
classpath "com.likethesalad.android:stem-plugin:2.3.0"
classpath 'org.owasp:dependency-check-gradle:8.0.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.20"
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
classpath libs.squareup.paparazziPlugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@ -38,12 +41,16 @@ buildscript {
plugins {
// ktlint Plugin
id "org.jlleitschuh.gradle.ktlint" version "10.3.0"
id "org.jlleitschuh.gradle.ktlint" version "11.1.0"
// Detekt
id "io.gitlab.arturbosch.detekt" version "1.20.0"
id "io.gitlab.arturbosch.detekt" version "1.22.0"
// Ksp
id "com.google.devtools.ksp" version "1.8.0-1.0.8"
// Dependency Analysis
id 'com.autonomousapps.dependency-analysis' version "1.9.0"
id 'com.autonomousapps.dependency-analysis' version "1.18.0"
// Gradle doctor
id "com.osacky.doctor" version "0.8.1"
}
// https://github.com/jeremylong/DependencyCheck
@ -56,6 +63,9 @@ dependencyCheck {
]
}
// Gradle doctor configuration
apply from: './tools/gradle/doctor.gradle'
allprojects {
apply plugin: "org.jlleitschuh.gradle.ktlint"
apply plugin: "io.gitlab.arturbosch.detekt"
@ -69,6 +79,14 @@ allprojects {
groups.mavenCentral.group.each { includeGroup it }
}
}
// snapshots repository
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
content {
groups.snapshot.regex.each { includeGroupByRegex it }
groups.snapshot.group.each { includeGroup it }
}
}
maven {
url 'https://jitpack.io'
content {
@ -78,9 +96,9 @@ allprojects {
}
// Jitsi repo
maven {
url "https://github.com/vector-im/jitsi_libre_maven/raw/main/android-sdk-5.0.2"
url "https://github.com/vector-im/jitsi_libre_maven/raw/main/android-sdk-6.2.2"
// Note: to test Jitsi release you can use a local file like this:
// url "file:///Users/bmarty/workspaces/jitsi_libre_maven/android-sdk-3.10.0"
// url "file:///Users/bmarty/workspaces/jitsi_libre_maven/android-sdk-6.2.2"
content {
groups.jitsi.regex.each { includeGroupByRegex it }
groups.jitsi.group.each { includeGroup it }
@ -125,6 +143,14 @@ allprojects {
enableExperimentalRules = true
// display the corresponding rule
verbose = true
reporters {
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.PLAIN)
// To have XML report for Danger
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
}
filter {
exclude { element -> element.file.path.contains("$buildDir/generated/") }
}
disabledRules = [
// TODO Re-enable these 4 rules after reformatting project
"indent",
@ -145,6 +171,8 @@ allprojects {
"experimental:comment-wrapping",
// - A KDoc comment after any other element on the same line must be separated by a new line
"experimental:kdoc-wrapping",
// Ignore error "Redundant curly braces", since we use it to fix false positives, for instance in "elementLogs.${i}.txt"
"string-template",
]
}
@ -207,7 +235,7 @@ project(":vector") {
}
}
project(":library:diff-match-patch") {
project(":library:external:diff-match-patch") {
sonarqube {
skipProject = true
}
@ -278,3 +306,61 @@ dependencyAnalysis {
}
}
}
tasks.register("recordScreenshots", GradleBuild) {
startParameter.projectProperties.screenshot = ""
tasks = [':vector:recordPaparazziDebug']
}
tasks.register("verifyScreenshots", GradleBuild) {
startParameter.projectProperties.screenshot = ""
tasks = [':vector:verifyPaparazziDebug']
}
ext.initScreenshotTests = { project ->
def hasScreenshots = project.hasProperty("screenshot")
if (hasScreenshots) {
project.apply plugin: 'app.cash.paparazzi'
}
project.dependencies { testCompileOnly libs.squareup.paparazzi }
project.android.testOptions.unitTests.all {
def screenshotTestCapture = "**/*ScreenshotTest*"
if (hasScreenshots) {
include screenshotTestCapture
} else {
exclude screenshotTestCapture
}
}
}
// Workaround to have KSP generated Kotlin code available in the IDE (for code completion)
// Ref: https://github.com/airbnb/epoxy/releases/tag/5.0.0beta02
subprojects { project ->
afterEvaluate {
if (project.hasProperty("android")) {
android {
if (it instanceof com.android.build.gradle.LibraryExtension) {
libraryVariants.all { variant ->
def outputFolder = new File("build/generated/ksp/${variant.name}/kotlin")
if (outputFolder.exists()) {
variant.addJavaSourceFoldersToModel(outputFolder)
android.sourceSets.getAt(variant.name).java {
srcDir(outputFolder)
}
}
}
} else if (it instanceof com.android.build.gradle.AppExtension) {
applicationVariants.all { variant ->
def outputFolder = new File("build/generated/ksp/${variant.name}/kotlin")
if (outputFolder.exists()) {
variant.addJavaSourceFoldersToModel(outputFolder)
android.sourceSets.getAt(variant.name).java {
srcDir(outputFolder)
}
}
}
}
}
}
}
}

View file

@ -1 +0,0 @@
FTUE - Adds support for resetting the password during the FTUE onboarding journey

View file

@ -1 +0,0 @@
Adds LoginType to SessionParams to fix soft logout form not showing for SSO and Password type

View file

@ -1 +0,0 @@
Improve user experience when he is first invited to a room. Users will be able to decrypt and view previous messages

View file

@ -1 +0,0 @@
Use stable endpoint for alias management instead of MSC2432. Contributed by Nico.

View file

@ -1 +0,0 @@
Replacing Epoxy annotation layout id references with getDefaultLayoutId

View file

@ -1 +0,0 @@
Ensure `RealmList<T>.clearWith()` extension is correctly used.

View file

@ -1 +0,0 @@
[Location sharing] - Reply action on a live message

View file

@ -1 +0,0 @@
Show a loader if all the Room Members are not yet loaded.

View file

@ -1 +0,0 @@
[Poll] - Add a description under undisclosed poll when not ended

View file

@ -1 +0,0 @@
Add `android:hasFragileUserData="true"` in the manifest

View file

@ -1 +0,0 @@
[Poll] Fixes visible and wrong votes in closed poll after removing 2 previous polls

View file

@ -1 +0,0 @@
Add code check to prevent modification of frozen class

View file

@ -1 +0,0 @@
Fix HTML entities being displayed in messages

View file

@ -1 +0,0 @@
Gallery picker can pick external images

1
changelog.d/7864.sdk Normal file
View file

@ -0,0 +1 @@
[Poll] Adding PollHistoryService

1
changelog.d/7864.wip Normal file
View file

@ -0,0 +1 @@
[Poll] History list: unmock data

1
changelog.d/7975.bugfix Normal file
View file

@ -0,0 +1 @@
Fix extra new lines added to inline code

1
changelog.d/8005.sdk Normal file
View file

@ -0,0 +1 @@
[Push rules] Call /actions api before /enabled api

1
changelog.d/8011.feature Normal file
View file

@ -0,0 +1 @@
[Rich text editor] Add inline code to rich text editor

1
changelog.d/8012.bugfix Normal file
View file

@ -0,0 +1 @@
[Voice Broadcast] Use internal playback timer to compute the current playback position

1
changelog.d/8031.bugfix Normal file
View file

@ -0,0 +1 @@
Do not send any request to Posthog if no consent is provided.

1
changelog.d/8042.misc Normal file
View file

@ -0,0 +1 @@
[Voice Broadcast] Show Live broadcast in the room list only if the feature flag is enabled in the lab

2
changelog.d/8062.bugfix Normal file
View file

@ -0,0 +1,2 @@
[Voice Broadcast] We should not be able to start broadcasting if there is already a live broadcast in the Room

View file

@ -7,6 +7,7 @@ def excludes = [
'**/*Activity*',
'**/*Fragment*',
'**/*Application*',
'**/*AndroidService*',
// We would like to exclude android widgets as well but our naming is inconsistent
@ -73,18 +74,18 @@ def collectProjects(predicate) {
task generateCoverageReport(type: JacocoReport) {
outputs.upToDateWhen { false }
rootProject.apply plugin: 'jacoco'
def projects = collectProjects { ['vector', 'matrix-sdk-android'].contains(it.name) }
def projects = collectProjects { ['vector-app', 'vector', 'matrix-sdk-android'].contains(it.name) }
initializeReport(it, projects, excludes)
}
task unitTestsWithCoverage(type: GradleBuild) {
// the 7.1.3 android gradle plugin has a bug where enableTestCoverage generates invalid coverage
startParameter.projectProperties.coverage = [enableTestCoverage: false]
tasks = [':vector:testGplayDebugUnitTest', ':matrix-sdk-android:testDebugUnitTest']
startParameter.projectProperties.coverage = "false"
tasks = ['testDebugUnitTest']
}
task instrumentationTestsWithCoverage(type: GradleBuild) {
startParameter.projectProperties.coverage = [enableTestCoverage: true]
startParameter.projectProperties.coverage = "true"
startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui'
tasks = [':vector:connectedGplayDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
tasks = [':vector-app:connectedGplayDebugAndroidTest', ':vector:connectedDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
}

View file

@ -1,47 +1,47 @@
ext.versions = [
'minSdk' : 21,
'compileSdk' : 31,
'targetSdk' : 31,
'compileSdk' : 33,
'targetSdk' : 33,
'sourceCompat' : JavaVersion.VERSION_11,
'targetCompat' : JavaVersion.VERSION_11,
]
// Pinned to 7.1.3 because of https://github.com/vector-im/element-android/issues/6142
// Please test carefully before upgrading again.
def gradle = "7.1.3"
def gradle = "7.4.1"
// Ref: https://kotlinlang.org/releases.html
def kotlin = "1.6.21"
def kotlinCoroutines = "1.6.3"
def dagger = "2.42"
def kotlin = "1.8.0"
def kotlinCoroutines = "1.6.4"
def dagger = "2.44.2"
def firebaseBom = "31.2.0"
def appDistribution = "16.0.0-beta05"
def retrofit = "2.9.0"
def arrow = "0.8.2"
def markwon = "4.6.2"
def moshi = "1.13.0"
def lifecycle = "2.4.1"
def moshi = "1.14.0"
def lifecycle = "2.5.1"
def flowBinding = "1.2.0"
def flipper = "0.152.0"
def epoxy = "4.6.2"
def mavericks = "2.7.0"
def glide = "4.13.2"
def flipper = "0.177.0"
def epoxy = "5.0.0"
def mavericks = "3.0.1"
def glide = "4.14.2"
def bigImageViewer = "1.8.1"
def jjwt = "0.11.5"
def vanniktechEmoji = "0.15.0"
def fragment = "1.4.1"
// Temporary version to unblock #6929. Once 0.16.0 is released we should use it, and revert
// the whole commit which set version 0.16.0-SNAPSHOT
def vanniktechEmoji = "0.16.0-SNAPSHOT"
def sentry = "6.13.0"
// Use 1.6.0 alpha to fix issue with test
def fragment = "1.6.0-alpha04"
// Testing
def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819
def espresso = "3.4.0"
def androidxTest = "1.4.0"
def androidxOrchestrator = "1.4.1"
def espresso = "3.5.1"
def androidxTest = "1.5.0"
def androidxOrchestrator = "1.4.2"
def paparazzi = "1.1.0"
ext.libs = [
gradle : [
'gradlePlugin' : "com.android.tools.build:gradle:$gradle",
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin",
'hiltPlugin' : "com.google.dagger:hilt-android-gradle-plugin:$dagger"
],
jetbrains : [
'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines",
@ -49,21 +49,20 @@ ext.libs = [
'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines"
],
androidx : [
'annotation' : "androidx.annotation:annotation:1.4.0",
'activity' : "androidx.activity:activity:1.4.0",
'annotations' : "androidx.annotation:annotation:1.3.0",
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
'activity' : "androidx.activity:activity-ktx:1.6.1",
'appCompat' : "androidx.appcompat:appcompat:1.6.0",
'biometric' : "androidx.biometric:biometric:1.1.0",
'core' : "androidx.core:core-ktx:1.8.0",
'core' : "androidx.core:core-ktx:1.9.0",
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3",
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.5",
'fragmentKtx' : "androidx.fragment:fragment-ktx:$fragment",
'fragmentTesting' : "androidx.fragment:fragment-testing:$fragment",
'fragmentTestingManifest' : "androidx.fragment:fragment-testing-manifest:$fragment",
'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.4",
'work' : "androidx.work:work-runtime-ktx:2.7.1",
'autoFill' : "androidx.autofill:autofill:1.1.0",
'preferenceKtx' : "androidx.preference:preference-ktx:1.2.0",
'junit' : "androidx.test.ext:junit:1.1.3",
'junit' : "androidx.test.ext:junit:1.1.5",
'lifecycleCommon' : "androidx.lifecycle:lifecycle-common:$lifecycle",
'lifecycleLivedata' : "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle",
'lifecycleProcess' : "androidx.lifecycle:lifecycle-process:$lifecycle",
@ -83,7 +82,13 @@ ext.libs = [
'transition' : "androidx.transition:transition:1.2.0",
],
google : [
'material' : "com.google.android.material:material:1.6.1"
'material' : "com.google.android.material:material:1.7.0",
'firebaseBom' : "com.google.firebase:firebase-bom:$firebaseBom",
'messaging' : "com.google.firebase:firebase-messaging",
'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution",
'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution",
// Phone number https://github.com/google/libphonenumber
'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.13.5"
],
dagger : [
'dagger' : "com.google.dagger:dagger:$dagger",
@ -96,23 +101,27 @@ ext.libs = [
'flipper' : "com.facebook.flipper:flipper:$flipper",
'flipperNetworkPlugin' : "com.facebook.flipper:flipper-network-plugin:$flipper",
],
element : [
'opusencoder' : "io.element.android:opusencoder:1.1.0",
'wysiwyg' : "io.element.android:wysiwyg:0.18.0"
],
squareup : [
'moshi' : "com.squareup.moshi:moshi:$moshi",
'moshiKt' : "com.squareup.moshi:moshi-kotlin:$moshi",
'moshiKotlin' : "com.squareup.moshi:moshi-kotlin-codegen:$moshi",
'moshiAdapters' : "com.squareup.moshi:moshi-adapters:$moshi",
'paparazzi' : "app.cash.paparazzi:paparazzi:$paparazzi",
'paparazziPlugin' : "app.cash.paparazzi:paparazzi-gradle-plugin:$paparazzi",
'retrofit' : "com.squareup.retrofit2:retrofit:$retrofit",
'retrofitMoshi' : "com.squareup.retrofit2:converter-moshi:$retrofit"
],
rx : [
'rxKotlin' : "io.reactivex.rxjava2:rxkotlin:2.4.0"
],
arrow : [
'core' : "io.arrow-kt:arrow-core:$arrow",
'instances' : "io.arrow-kt:arrow-instances-core:$arrow"
],
markwon : [
'core' : "io.noties.markwon:core:$markwon",
'extLatex' : "io.noties.markwon:ext-latex:$markwon",
'imageGlide' : "io.noties.markwon:image-glide:$markwon",
'inlineParser' : "io.noties.markwon:inline-parser:$markwon",
'html' : "io.noties.markwon:html:$markwon"
],
@ -125,7 +134,7 @@ ext.libs = [
'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks"
],
maplibre : [
'androidSdk' : "org.maplibre.gl:android-sdk:9.5.2",
'androidSdk' : "org.maplibre.gl:android-sdk:9.6.0",
'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:1.0.0"
],
mockk : [
@ -156,12 +165,15 @@ ext.libs = [
'emojiGoogle' : "com.vanniktech:emoji-google:$vanniktechEmoji"
],
apache : [
'commonsImaging' : "org.apache.sanselan:sanselan:0.97-incubator"
'commonsImaging' : "org.apache.commons:commons-imaging:1.0-alpha3"
],
sentry: [
'sentryAndroid' : "io.sentry:sentry-android:$sentry"
],
tests : [
'kluent' : "org.amshove.kluent:kluent-android:1.68",
'kluent' : "org.amshove.kluent:kluent-android:1.72",
'timberJunitRule' : "net.lachlanmckee:timber-junit-rule:1.0.1",
'junit' : "junit:junit:4.13.2"
'junit' : "junit:junit:4.13.2",
]
]

View file

@ -38,10 +38,18 @@ ext.groups = [
'com.google.testing.platform',
]
],
snapshot: [
regex: [
],
group: [
'com.vanniktech',
]
],
mavenCentral: [
regex: [
],
group: [
'app.cash.paparazzi',
'ch.qos.logback',
'com.adevinta.android',
'com.airbnb.android',
@ -69,14 +77,14 @@ ext.groups = [
'com.gabrielittner.threetenbp',
'com.getkeepsafe.relinker',
'com.github.bumptech.glide',
'com.github.filippudak',
'com.github.filippudak.progresspieview',
'com.github.javaparser',
'com.github.piasy',
'com.github.shyiko.klob',
'com.github.rubensousa',
'com.google',
'com.google.android',
'com.google.api.grpc',
'com.google.auto',
'com.google.auto.service',
'com.google.auto.value',
'com.google.code.findbugs',
@ -94,6 +102,7 @@ ext.groups = [
'com.googlecode.json-simple',
'com.googlecode.libphonenumber',
'com.ibm.icu',
'com.intellij',
'com.jakewharton.android.repackaged',
'com.jakewharton.timber',
'com.kgurgul.flipper',
@ -106,7 +115,9 @@ ext.groups = [
'com.pinterest.ktlint',
'com.posthog.android',
'com.squareup',
'com.squareup.curtains',
'com.squareup.duktape',
'com.squareup.leakcanary',
'com.squareup.moshi',
'com.squareup.okhttp3',
'com.squareup.okio',
@ -117,13 +128,14 @@ ext.groups = [
'com.sun.xml.bind.mvn',
'com.sun.xml.fastinfoset',
'com.thoughtworks.qdox',
'com.vanniktech',
// 'com.vanniktech',
'commons-cli',
'commons-codec',
'commons-io',
'commons-logging',
'info.picocli',
'io.arrow-kt',
'io.element.android',
'io.github.davidburstrom.contester',
'io.github.detekt.sarif4k',
'io.github.microutils',
'io.github.reactivecircus.flowbinding',
@ -135,16 +147,21 @@ ext.groups = [
'io.netty',
'io.noties.markwon',
'io.opencensus',
'io.perfmark',
'io.reactivex.rxjava2',
'io.realm',
'io.sentry',
'it.unimi.dsi',
'jakarta.activation',
'jakarta.xml.bind',
'javax.activation',
'javax.annotation',
'javax.inject',
'javax.xml.bind',
'jline',
'jp.wasabeef',
'junit',
'kxml2',
'me.saket',
'net.bytebuddy',
'net.java',
@ -159,8 +176,8 @@ ext.groups = [
'org.apache.ant',
'org.apache.commons',
'org.apache.httpcomponents',
'org.apache.sanselan',
'org.bouncycastle',
'org.ccil.cowan.tagsoup',
'org.checkerframework',
'org.codehaus',
'org.codehaus.groovy',
@ -173,11 +190,13 @@ ext.groups = [
'org.hamcrest',
'org.jacoco',
'org.java-websocket',
'org.jcodec',
'org.jetbrains',
'org.jetbrains.dokka',
'org.jetbrains.intellij.deps',
'org.jetbrains.kotlin',
'org.jetbrains.kotlinx',
'org.jetbrains.trove4j',
'org.json',
'org.jsoup',
'org.junit',
@ -194,7 +213,6 @@ ext.groups = [
'org.ow2.asm',
'org.ow2.asm',
'org.reactivestreams',
'org.robolectric',
'org.slf4j',
'org.sonatype.oss',
'org.testng',

View file

@ -0,0 +1,259 @@
# Developer on boarding
<!--- TOC -->
* [Introduction](#introduction)
* [Quick introduction to Matrix](#quick-introduction-to-matrix)
* [Matrix data](#matrix-data)
* [Room](#room)
* [Event](#event)
* [Sync](#sync)
* [Glossary about syncs](#glossary-about-syncs)
* [The Android project](#the-android-project)
* [Matrix SDK](#matrix-sdk)
* [Application](#application)
* [MvRx](#mvrx)
* [Behavior](#behavior)
* [Epoxy](#epoxy)
* [Other frameworks](#other-frameworks)
* [Push](#push)
* [Dependencies management](#dependencies-management)
* [Test](#test)
* [Other points](#other-points)
* [Logging](#logging)
* [Rageshake](#rageshake)
* [Tips](#tips)
* [Happy coding!](#happy-coding)
<!--- END -->
## Introduction
This doc is a quick introduction about the project and its architecture.
It's aim is to help new developers to understand the overall project and where to start developing.
Other useful documentation:
- all the docs in this folder!
- the [contributing doc](../CONTRIBUTING.md), that you should also read carefully.
### Quick introduction to Matrix
Matrix website: [matrix.org](https://matrix.org), [discover page](https://matrix.org/discover).
*Note*: Matrix.org is also hosting a homeserver ([.well-known file](https://matrix.org/.well-known/matrix/client)).
The reference homeserver (this is how Matrix servers are called) implementation is [Synapse](https://github.com/matrix-org/synapse/). But other implementations exist. The Matrix specification is here to ensure that any Matrix client, such as Element Android and its SDK can talk to any Matrix server.
Have a quick look to the client-server API documentation: [Client-server documentation](https://spec.matrix.org/v1.3/client-server-api/). Other network API exist, the list is here: (https://spec.matrix.org/latest/)
Matrix is an open source protocol. Change are possible and are tracked using [this GitHub repository](https://github.com/matrix-org/matrix-doc/). Changes to the protocol are called MSC: Matrix Spec Change. These are PullRequest to this project.
Matrix object are Json data. Unstable prefixes must be used for Json keys when the MSC is not merged (i.e. accepted).
#### Matrix data
There are many object and data in the Matrix worlds. Let's focus on the most important and used, `Room` and `Event`
##### Room
`Room` is a place which contains ordered `Event`s. They are identified with their `room_id`. Nearly all the data are stored in rooms, and shared using homeserver to all the Room Member.
*Note*: Spaces are also Rooms with a different `type`.
##### Event
`Events` are items of a Room, where data is embedded.
There are 2 types of Room Event:
- Regular Events: contain useful content for the user (message, image, etc.), but are not necessarily displayed as this in the timeline (reaction, message edition, call signaling).
- State Events: contain the state of the Room (name, topic, etc.). They have a non null value for the key `state_key`.
Also all the Room Member details are in State Events: one State Event per member. In this case, the `state_key` is the matrixId (= userId).
Important Fields of an Event:
- `event_id`: unique across the Matrix universe;
- `room_id`: the room the Event belongs to;
- `type`: describe what the Event contain, especially in the `content` section, and how the SDK should handle this Event;
- `content`: dynamic Event data; depends on the `type`.
So we have a triple `event_id`, `type`, `state_key` which uniquely defines an Event.
#### Sync
The `Sync` is a way for the Matrix client to be up to date regarding the user data hosted by the server. All the Events are coming through the sync response. More details can be found here: [spec.matrix.org/v1.3/client-server-api/#syncing](https://spec.matrix.org/v1.3/client-server-api/#syncing)
When the application is in foreground, this is a looping request. We are using Https requests, which offer the advantage to be compatible with any homeserver. A sync token is used as request parameter, to let the server know what the client knows.
The `SyncThread` is responsible to manage the sync request loop.
When the application is in background, a Push will trigger a sync request.
##### Glossary about syncs
- **initial sync**: a sync request without a token. This is the first request a client perform after login or after a clear cache. The server will include in the response all your rooms with the full state (all the room membership Event will not be present), with the latest messages for each room. We are in the process to replace this by version 3: sliding sync. All data are inserted to the Database (currently [Realm](https://www.mongodb.com/docs/realm/sdk/java/)).
- **incremental sync**: sync request with a token.
- **gappy sync**: sync request where all the new Events are not returned for one or several Rooms. Also called `limited sync`. It can be limited per Room. To get all the missing Events, a Room pagination API has to be called.
- **sync token**: `next_batch` value in the previous sync response. Will be provided as the `since` parameter for the next sync request.
### The Android project
The project should compile out of the box.
The project is split into several modules. The main ones are:
For the app
- `vector-app`: application entry point;
- `vector`: legacy application, but now a library. In the process of being split into several modules;
- `vector-config`: this is where all the configuration of the application should occurs. Should because we are in the process of migrating all the configuration here;
- `library/ui-strings`: this is where all the string resources are stored. Please refer to [contributing doc](../CONTRIBUTING.md) to know how to make change on this module;
- `library/ui-styles`: this is where the Android styles are defined.
For the SDK
- `matrix-sdk-android`: the main SDK module. The sources are in this project, but are also exported to [its own project](https://github.com/matrix-org/matrix-android-sdk2). All the PRs and issues related to the SDK take place in the Element Android project;
- `matrix-sdk-android-flow`: contains some wrapper to expose `Flow` to the application.
### Matrix SDK
SDK exposes `Services` to the client application. `Services` are public interface, and are defined in this parent package: `org.matrix.android.sdk.api`. Default implementation are internal to the SDK, in this parent package: `org.matrix.android.sdk.internal`. Note that you also have to declare the classes as `internal` when adding classes to the `org.matrix.android.sdk.internal` package.
Interface allows us to replace the implementation for testing purpose.
A generated documentation of the SDK is available [here](https://matrix-org.github.io/matrix-android-sdk2/). Updated after each release. Please ensure that the documentation (KDoc) of all the SDK Services is up to date, and is clear for a SDK user.
The SDK generated documentation also contains information about the entry points of the SDK.
[Dagger](https://dagger.dev/) is used to inject all the dependencies to the SDK classes.
SDK is exposing data as `LiveData`, but we are progressively migrating to `Flow`. Database is the source of truth.
Example:
- Client send an Event using the `SendService`;
- At the end a `SendEvent` task is used;
- Retrofit API is used to send data to the server;
- Goes to the server, which returns only the `event_id`;
- The `Event` is coming back from the `sync` response with eventually extra added data.
### Application
This is the UI part of the project.
There are two variants of the application: `Gplay` and `Fdroid`.
The main difference is about using Firebase on `Gplay` variant, to have Push from Google Services. `FDroid` variant cannot contain closed source dependency.
`Fdroid` is using background polling to lack the missing of Pushed. Now a solution using UnifiedPush has ben added to the project. See refer to [the dedicated documentation](./unifiedpush.md) for more details.
#### MvRx
[Maverick](https://airbnb.io/mavericks/#/README) (or MvRx) is an Android MVI framework that helps to develop Reactive application on Android.
- Activity: holder for Fragment. See the parent [VectorBaseActivity](../vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt);
- Fragment: manage screen of the application. See the parent [VectorBaseFragment](../vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt);
- BottomSheet: see the parent [VectorBaseBottomSheetDialogFragment](../vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt);
- ViewModel: this is where the logic is placed. All our ViewModel has a `handle()` which takes action as parameter. See the parent [VectorViewModel](../vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt);
- VectorSharedActionViewModel: Specific ViewModel that can be used to communicate between Fragment(s) and the host Activity. See the parent [VectorSharedActionViewModel](../vector/src/main/java/im/vector/app/core/platform/VectorSharedActionViewModel.kt);
- ViewState: this are `data class`, and this represent the state of the View. Has to be copied and set to be updated. Fragment will update the UI regarding the current state (`invalidate()` method). `Async` class from MvRx can be used in the ViewState, especially for asynchronous data loading. Nullability can also be used for optional data. ViewStates have to implement `MavericksState`;
- ViewEvents: useful when the ViewModel asks the View to trigger a specific action: navigation, show dialog, etc. See the parent [VectorViewEvents](../vector/src/main/java/im/vector/app/core/platform/VectorViewEvents.kt);
- ViewAction (`VectorViewModelAction`): useful when the UI (generally the Fragment) asks the ViewModel to do something. See the parent [VectorViewModelAction](../vector/src/main/java/im/vector/app/core/platform/VectorViewModelAction.kt);
- Controller: see the `Epoxy` section just below.
##### Behavior
Fragment asks the ViewModel to perform an action (coming from the user, but not necessarily. ViewModel can then talk to the SDK, updates the state once or several times. Fragment update the UI regarding the new state.
When ViewModel is instantiated, it can subscribe using the SDK Services to get live state of the data.
`invalidate()` has to be used by default, but it's possible to listen to specific member(s) of the `ViewState` using `onEach`. TODO Add an example.
`awaitState()` method
#### Epoxy
[Epoxy](https://github.com/airbnb/epoxy) is an Android library for building complex screens in a RecyclerView. Please read [the introduction](https://github.com/airbnb/epoxy#epoxy).
- Controller declares items of the RecyclerView. Controller is injected in the Fragment. Controller extends `EpoxyController`, or one of its subclass, especially `TypedEpoxyController`;
- Fragment gives the state to the controller using `setData`;
- `buildModels` will be called by the framework;
- Controller will create ordered Items.
Epoxy does the diffing, and handle many other thing for us, like handling item type, etc.
See for instance the controller [AccountDataEpoxyController](../vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt)) for a simple example.
Warning: do not use twice the same item `id` or it will crash.
#### Other frameworks
- Dependency injection is managed by [Dagger](https://dagger.dev/) (SDK) and [Hilt](https://developer.android.com/training/dependency-injection/hilt-android) (App);
- [Retrofit](https://square.github.io/retrofit/) and [OkHttp3](https://square.github.io/okhttp/): network requests;
- [Moshi](https://github.com/square/moshi) is used to parse and serialize Json object;
### Push
Please see the dedicated documentation for more details.
This is the classical scenario:
- App receives a Push. Note: Push is ignored if app is in foreground;
- App asks the SDK to load Event data (fastlane mode). We have a change to get the data faster and display the notification faster;
- App asks the SDK to perform a sync request.
### Dependencies management
All the dependencies are declared in `build.gradle` files. But some versions are declared in [this dedicated file](../dependencies.gradle).
When adding a new dependency, you will have to update the file [dependencies_groups.gradle](../dependencies_groups.gradle) to allow the dependency to be downloaded from the artifact repository. Sometimes sub-dependencies need to be added too, until the project can compile.
[Dependabot](https://github.com/dependabot) is set up on the project. This tool will automatically create Pull Request to upgrade our dependencies one by one.
dependencies_group, gradle files, Dependabot, etc.
### Test
Please refer to [this dedicated document](./ui-tests.md).
TODO add link to the dedicated screenshot test documentation
### Other points
#### Logging
**Important warning: ** NEVER log private user data, or use the flag `LOG_PRIVATE_DATA`. Be very careful when logging `data class`, all the content will be output!
[Timber](https://github.com/JakeWharton/timber) is used to log data to logcat. We do not use directly the `Log` class. If possible please use a tag, as per
````kotlin
Timber.tag(loggerTag.value).d("my log")
````
because automatic tag (= class name) will not be available on the release version.
Also generally it is recommended to provide the `Throwable` to the Timber log functions.
Last point, not that `Timber.v` function may have no effect on some devices. Prefer using `Timber.d` and up.
#### Rageshake
Rageshake is a feature to send bug report directly from the application. Just shake your phone and you will be prompted to send a bug report.
Bug report can contain:
- a screenshot of the current application state
- the application logs from up to 15 application starts
- the logcat logs
- the key share history (crypto data)
The data will be sent to an internal server, which is not publicly accessible. A GitHub issue will also be created to a private GitHub repository.
Rageshake can be very useful to get logs from a release version of the application.
### Tips
- Element Android has a `developer mode` in the `Settings/Advanced settings`. Other useful options are available here;
- Show hidden Events can also help to debug feature. When developer mode is enabled, it is possible to view the source (= the Json content) of any Events;
- Type `/devtools` in a Room composer to access a developer menu. There are some other entry points. Developer mode has to be enabled;
- Hidden debug menu: when developer mode is enabled and on debug build, there are some extra screens that can be accessible using the green wheel. In those screens, it will be possible to toggle some feature flags;
- Using logcat, filtering with `onResume` can help you to understand what screen are currently displayed on your device. Searching for string displayed on the screen can also help to find the running code in the codebase.
- When this is possible, prefer using `sealed interface` instead of `sealed class`;
- When writing temporary code, using the string "DO NOT COMMIT" in a comment can help to avoid committing things by mistake. If committed and pushed, the CI will detect this String and will warn the user about it.
## Happy coding!
The team is here to support you, feel free to ask anything to other developers.
Also please feel to update this documentation, if incomplete/wrong/obsolete/etc.
**Thanks!**

106
docs/danger.md Normal file
View file

@ -0,0 +1,106 @@
## Danger
<!--- TOC -->
* [What does danger checks](#what-does-danger-checks)
* [PR check](#pr-check)
* [Quality check](#quality-check)
* [Setup](#setup)
* [Run danger locally](#run-danger-locally)
* [Danger user](#danger-user)
* [Useful links](#useful-links)
<!--- END -->
## What does danger checks
### PR check
See the [dangerfile](../tools/danger/dangerfile.js). If you add rules in the dangerfile, please update the list below!
Here are the checks that Danger does so far:
- PR description is not empty
- Big PR got a warning to recommend to split
- PR contains a file for towncrier and extension is checked
- PR does not modify frozen classes
- PR contains a Sign-Off, with exception for Element employee contributors
- PR with change on layout should include screenshot in the description
- PR which adds png file warn about the usage of vector drawables
- non draft PR should have a reviewer
- files containing translations are not modified by developers
### Quality check
After all the checks that generate checkstyle XML report, such as Ktlint, lint, or Detekt, Danger is run with this [dangerfile](../tools/danger/dangerfile-lint.js), in order to post comments to the PR with the detected error and warnings.
To run locally, you will have to install the plugin `danger-plugin-lint-report` using:
```shell
yarn add danger-plugin-lint-report --dev
```
## Setup
This operation should not be necessary, since Danger is already setup for the project.
To setup danger to the project, run:
```shell
bundle exec danger init
```
## Run danger locally
When modifying the [dangerfile](../tools/danger/dangerfile.js), you can check it by running Danger locally.
To run danger locally, install it and run:
```shell
bundle exec danger pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
```
For instance:
```shell
bundle exec danger pr https://github.com/vector-im/element-android/pull/6637 --dangerfile=./tools/danger/dangerfile.js
```
We may need to create a GitHub token to have less API rate limiting, and then set the env var:
```shell
export DANGER_GITHUB_API_TOKEN='YOUR_TOKEN'
```
Swift and Kotlin (just in case)
```shell
bundle exec danger-swift pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
bundle exec danger-kotlin pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
```
## Danger user
To let Danger check all the PRs, including PRs form forks, a GitHub account have been created:
- login: ElementBot
- password: Stored on Passbolt
- GitHub token: A token with limited access has been created and added to the repository https://github.com/vector-im/element-android as secret DANGER_GITHUB_API_TOKEN. This token is not saved anywhere else. In case of problem, just delete it and create a new one, then update the secret.
PRs from forks do not always have access to the secret `secrets.DANGER_GITHUB_API_TOKEN`, so `secrets.GITHUB_TOKEN` is also provided to the job environment. If `secrets.DANGER_GITHUB_API_TOKEN` is available, it will be used, so user `ElementBot` will comment the PR. Else `secrets.GITHUB_TOKEN` will be used, and bot `github-actions` will comment the PR.
## Useful links
- https://danger.systems/
- https://danger.systems/js/
- https://danger.systems/js/guides/getting_started.html
- https://danger.systems/js/reference.html
- https://github.com/danger/awesome-danger
Some danger files to get inspired from
- https://github.com/artsy/emission/blob/master/dangerfile.ts
- https://github.com/facebook/react-native/blob/master/bots/dangerfile.js
- https://github.com/apollographql/apollo-client/blob/master/config/dangerfile.ts
- https://github.com/styleguidist/react-styleguidist/blob/master/dangerfile.js
- https://github.com/storybooks/storybook/blob/master/dangerfile.js
- https://github.com/ReactiveX/rxjs/blob/master/dangerfile.js

View file

@ -0,0 +1,55 @@
<!--- TOC -->
* [Testing database migration](#testing-database-migration)
* [Creating a reference database](#creating-a-reference-database)
* [Testing](#testing)
<!--- END -->
## Testing database migration
### Creating a reference database
Databases are encrypted, the key to decrypt is needed to setup the test.
A special build property must be enabled to extract it.
Set `vector.debugPrivateData=true` in `~/.gradle/gradle.properties` (to avoid committing by mistake)
Launch the app in your emulator, login and use the app to fill up the database.
Save the key for the tested database
```
RealmKeysUtils W Database key for alias `session_db_fe9f212a611ccf6dea1141777065ed0a`: 935a6dfa0b0fc5cce1414194ed190....
RealmKeysUtils W Database key for alias `crypto_module_fe9f212a611ccf6dea1141777065ed0a`: 7b9a21a8a311e85d75b069a343.....
```
Use the [Device File Explorer](https://developer.android.com/studio/debug/device-file-explorer) to extrat the database file from the emulator.
Go to `data/data/im.vector.app.debug/files/<hash>/`
Pick the database you want to test (name can be found in SessionRealmConfigurationFactory):
- crypto_store.realm for crypto
- disk_store.realm for session
- etc...
Download the file on your disk
### Testing
Copy the file in `src/AndroidTest/assets`
see `CryptoSanityMigrationTest` or `RealmSessionStoreMigration43Test` for sample tests.
There are already some databases in the assets folder.
The existing test will properly detect schema changes, and fail with such errors if a migration is missing:
```
io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
- Property 'CryptoMetadataEntity.foo' has been added.
```
If you want to test properly more complex database migration (dynamic transforms) ensure that the database contains
the entity you want to migrate.
You can explore the database with [realm studio](https://www.mongodb.com/docs/realm/studio/) if needed.

View file

@ -7,8 +7,8 @@ Hilt is built on top of Dagger 2 and simplify usage by removing needs to create
When you create a new feature, you should have the following:
Annotate your Activity with @AndroidEntryPoint
Annotate your Fragment with @AndroidEntryPoint
If you have a BottomSheetFragment => Annotate it with @AndroidEntryPoint
Otherwise => Add your Fragment to the FragmentModule
Add your ViewModel.Factory to the MavericksViewModelModule
Makes sure your ViewModel as the following code:

View file

@ -0,0 +1,52 @@
## Installing from CI
<!--- TOC -->
* [Installing from Buildkite](#installing-from-buildkite)
* [Installing from GitHub](#installing-from-github)
* [Create a GitHub token](#create-a-github-token)
* [Provide artifact URL](#provide-artifact-url)
* [Next steps](#next-steps)
* [Future improvement](#future-improvement)
<!--- END -->
Installing APK build by the CI is possible
### Installing from Buildkite
The script `./tools/install/installFromBuildkite.sh` can be used, but Builkite will be removed soon. See next section.
### Installing from GitHub
To install an APK built by a GitHub action, run the script `./tools/install/installFromGitHub.sh`. You will need to pass a GitHub token to do so.
#### Create a GitHub token
You can create a GitHub token going to your Github account, at this page: [https://github.com/settings/tokens](https://github.com/settings/tokens).
You need to create a token (classic) with the scope `repo/public_repo`. So just check the corresponding checkbox.
Validity can be long since the scope of this token is limited. You will still be able to delete the token and generate a new one.
Click on Generate token and save the token locally.
### Provide artifact URL
The script will ask for an artifact URL. You can get this artifact URL by following these steps:
- open the pull request
- in the check at the bottom, click on `APK Build / Build debug APKs`
- click on `Summary`
- scroll to the bottom of the page
- copy the link `vector-Fdroid-debug` if you want the F-Droid variant or `vector-Gplay-debug` if you want the Gplay variant.
The copied link can be provided to the script.
### Next steps
The script will download the artifact, unzip it and install the correct version (regarding arch) on your device.
Files will be added to the folder `./tmp/DebugApks`. Feel free to cleanup this folder from time to time, the script will not delete files.
### Future improvement
The script could ask the user for a Pull Request number and Gplay/Fdroid choice like it was done with Buildkite script. Using GitHub API may be possible to do that.

View file

@ -93,4 +93,4 @@ url "https://github.com/vector-im/jitsi_libre_maven/raw/master/android-sdk-3.10.
- Build the project and perform the sanity tests again.
- Update the file `/CHANGES.md` to notify about the library upgrade, and create a regular PR for project Element Android.
- Create a PR for project Element Android and add a changelog file `<PR_NUMBER>.misc` to notify about the library upgrade.

54
docs/nightly_build.md Normal file
View file

@ -0,0 +1,54 @@
# Nightly builds
<!--- TOC -->
* [Configuration](#configuration)
* [How to register to get nightly build](#how-to-register-to-get-nightly-build)
* [Build nightly manually](#build-nightly-manually)
<!--- END -->
## Configuration
The nightly build will contain what's on develop, in release mode, for Gplay variant. It is signed using a dedicated signature, and has a dedicated appId (`im.vector.app.nightly`), so it can be installed along with the production version of Element Android. The only other difference compared to Element Android is a different app icon background. We do not want to change the app name since it will also affect some strings in the app, and we do want to do that.
Nightly builds are built and released to Firebase every days, and automatically.
This is recommended to exclusively use this app, with your main account, instead of Element Android, and fallback to Element Android just in case of regression, to discover as soon as possible any regression, and report it to the team. To avoid double notification, you may want to disable the notification from the Element Android production version. Just open Element Android, navigate to `Settings/Notifications` and uncheck `Enable notifications for this session`.
*Note:* Due to a limitation of Firebase, the nightly build is the universal build, which means that the size of the APK is a bit bigger, but this should not have any other side effect.
## How to register to get nightly build
Provide your email to the Android team, who will add it to the list "External testers" on Firebase. You will then receive an invite on the provided email.
Follow the instructions on the email to install the latest nightly build. This is not clear yet if new nightly build will be automatically installed or not.
## Build nightly manually
Nightly build can be built manually from your computer. You will need to retrieved some secrets from Passbolt and add them to your file `~/.gradle/gradle.properties`:
```
signing.element.nightly.storePassword=VALUE_FROM_PASSBOLT
signing.element.nightly.keyId=VALUE_FROM_PASSBOLT
signing.element.nightly.keyPassword=VALUE_FROM_PASSBOLT
```
You will also need to add the environment variable `FIREBASE_TOKEN`:
```sh
export FIREBASE_TOKEN=VALUE_FROM_PASSBOLT
```
Then you can run the following commands (which are also used in the file for [the GitHub action](../.github/workflows/nightly.yml)):
```sh
git checkout develop
mv towncrier.toml towncrier.toml.bak
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
rm towncrier.toml.bak
yes n | towncrier build --version nightly
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
```
Then you can reset the change on the codebase.

View file

@ -191,7 +191,7 @@ Examples of prefixes:
- `[Bugfix]`
- etc.
Also, it's still possible to add labels to the PRs, such as `A-` or `T-` labels, even if this is not a string requirement. We prefer to spend time to add labels on issues.
Also, it's still possible to add labels to the PRs, such as `A-` or `T-` labels, even if this is not a strong requirement. We prefer to spend time to add labels on issues.
##### PR description

View file

@ -0,0 +1,72 @@
# Screenshot testing
<!--- TOC -->
* [Overview](#overview)
* [Setup](#setup)
* [Recording](#recording)
* [Verifying](#verifying)
* [Contributing](#contributing)
* [Example](#example)
<!--- END -->
## Overview
- Screenshot tests are tests which record the content of a rendered screen and verify subsequent runs to check if the screen renders differently.
- Element uses [Paparazzi](https://github.com/cashapp/paparazzi) to render, record and verify android layouts.
- The screenshot verification occurs on every pull request as part of the `tests.yml` workflow.
## Setup
- Install Git LFS through your package manager of choice (`brew install git-lfs` | `yay -S git-lfs`).
- Install the Git LFS hooks into the project.
```bash
# with element-android as the current working directory
git lfs install --local
```
- If installed correctly, `git push` and `git pull` will now include LFS content.
## Recording
- `./gradlew recordScreenshots`
- Paparazzi will generate images in `${module}/src/test/snapshots`, which will need to be committed to the repository using Git LFS.
## Verifying
- `./gradlew verifyScreenshots`
- In the case of failure, Paparazzi will generate images in `${module}/out/failure`. The images will show the expected and actual screenshots along with a delta of the two images.
## Contributing
- When creating a test, the file (and class) name names must include `ScreenshotTest`, eg `ItemScreenshotTest`.
- After creating the new test, record and commit the newly rendered screens.
- `./tools/validate_lfs` can be ran to ensure everything is working correctly with Git LFS, the CI also runs this check.
## Example
```kotlin
class PaparazziExampleScreenshotTest {
@get:Rule
val paparazzi = Paparazzi(
deviceConfig = PIXEL_3,
theme = "Theme.Vector.Light",
)
@Test
fun `example paparazzi test`() {
// Inflate the layout
val view = paparazzi.inflate<ConstraintLayout>(R.layout.item_radio)
// Bind data to the view
view.findViewById<TextView>(R.id.actionTitle).text = paparazzi.resources.getString(R.string.room_settings_all_messages)
view.findViewById<ImageView>(R.id.radioIcon).setImageResource(R.drawable.ic_radio_on)
// Record the bound view
paparazzi.snapshot(view)
}
}
```

View file

@ -18,7 +18,7 @@ The recently started UnifiedPush project is an Android protocol and library for
The *F-Droid* and *Gplay* flavors of Element Android support UnifiedPush, so the user can use any distributor installed on their devices. This would make it possible to have push notifications without depending on Google services or libraries. Currently, the main distributors are [ntfy](https://ntfy.sh) which does not require any setup (like manual registration) to use the public server and [NextPush](https://github.com/UP-NextPush/android), available as a nextcloud application.
The *Gplay* variant uses a UnifiedPush library which basically embed a FCM distributor built into the application (so a user doesn't need to do anything other than install the app to get FCM notifications). This variant uses Google Services to receive notifications if the user has not installed any distributor.
The *Gplay* variant uses a UnifiedPush library which basically embed a FCM distributor built into the application (so a user doesn't need to do anything other than install the app to get FCM notifications). This variant uses Google Services to receive notifications if the user has not installed any distributor. A [FCM Rewrite Proxy](https://unifiedpush.org/developers/embedded_fcm/#fcm-rewrite-proxy) is not required for Element Android's implementation of the FCM distributor - it will work with an existing Matrix push provider, such as [Sygnal](https://github.com/matrix-org/sygnal).
The *F-Droid* variant does not use this library to avoid any proprietary blob. It will use a polling service if the user has not installed any distributor.

351
docs/unit_testing.md Normal file
View file

@ -0,0 +1,351 @@
# Table of Contents
<!--- TOC -->
* [Overview](#overview)
* [Best Practices](#best-practices)
* [Project Conventions](#project-conventions)
* [Setup](#setup)
* [Naming](#naming)
* [Format](#format)
* [Assertions](#assertions)
* [Constants](#constants)
* [Mocking](#mocking)
* [Fakes](#fakes)
* [Fixtures](#fixtures)
* [Examples](#examples)
* [Extensions used to streamline the test setup](#extensions-used-to-streamline-the-test-setup)
* [Fakes and Fixtures](#fakes-and-fixtures)
<!--- END -->
## Overview
Unit tests are a mechanism to validate our code executes the way we expect. They help to inform the design of our systems by requiring testability and
understanding, they describe the inner workings without relying on inline comments and protect from unexpected regressions.
However, unit tests are not a magical solution to solve all our problems and come at a cost. Unreliable and hard to maintain tests often end up ignored, deleted
or worse, provide a false sense of security.
### Best Practices
Tests can be written in many ways, the main rule is to keep them simple and maintainable. Some ways to help achieve this are...
- Break out logic into single units (following the Single Responsibility Principle) to reduce test complexity.
- Favour pure functions, avoiding mutable state.
- Prefer dependency injection to static calls to allow for simpler test setup.
- Write concise tests with a single function under test, clearly showing the inputs and expected output.
- Create separate test cases instead of changing parameters and grouping multiple assertions within a single test to help trace back failure causes (with the
exception of parameterised tests).
- Assert against entire models instead of subsets of properties to capture any possible changes within the test scope.
- Avoid invoking logic from production instances other than the class under test to guard from unrelated changes.
- Always inject `Dispatchers` and `Clock` instances and provide fake implementations for tests to avoid non deterministic results.
## Project Conventions
#### Setup
- Test file and class name should be the class under test with the Test suffix, created in a `test` sourceset, with the same package name as the class under
test.
- Dependencies of the class are instantiated inline, junit will recreate the test class for each test run.
- A line break between the dependencies and class under test helps clarify the instance being tested.
```kotlin
class MyClassTest {
private val fakeUppercaser = FakeUppercaser()
// line break between the class under test and its dependencies
private val myClass = MyClass(fakeUppercaser.instance)
}
```
#### Naming
- Test names use the `Gherkin` format, `given, when, then` mapping to the input, logic under test and expected result.
- `given` - Uniqueness about the environment or dependencies in which the test case is running. _"given device is android 12 and supports dark mode"_
- `when` - The action/function under test. _"when reading dark mode status"_
- `then` - The expected result from the combination of _given_ and _when_. _"then returns dark mode enabled"_
- Test names are written using kotlin back ticks to enable sentences _ish_.
```kotlin
@Test
fun `given a lowercase label, when uppercasing, then returns label uppercased`
```
When the input is given directly to the _when_, this can also be represented as...
```kotlin
@Test
fun `when uppercasing a lowercase label, then returns label uppercased`
```
Multiple given or returns statements can be used in the name although it could be a sign that the logic being tested does too much.
---
#### Format
- Test bodies are broken into sections through the use of blank lines where the sections correspond to the test name.
- Sections can span multiple lines.
```kotlin
// comments are for illustrative purposes
/* given */ val lowercaseLabel = "hello world"
/* when */ val result = textUppercaser.uppercase(lowercaseLabel)
/* then */ result shouldBeEqualTo "HELLO WORLD"
```
- Functions extracted from test bodies are placed beneath all the unit tests.
---
#### Assertions
- Assertions against test results are made using [Kluent's](https://github.com/MarkusAmshove/Kluent) _fluent_ api.
- Typically `shouldBeEqualTo`is the main assertion to use for asserting function return values as by project convention we assert against entire objects or
lists.
```kotlin
val result = listOf("hello", "world")
// Fail
result shouldBeEqualTo listOf("hello")
```
```kotlin
data class Person(val age: Int, val name: String)
val result = Person(age = 100, name = "Gandalf")
// Avoid
result.age shouldBeEqualTo 100
// Prefer
result shouldBeEqualTo Person(age = 100, "Gandalf")
```
- Exception throwing can be asserted against using `assertFailsWith<T : Throwable>`.
- When asserting reusable exceptions, include the message to distinguish between them.
```kotlin
assertFailsWith<ConcreteException>(message = "Details about error") {
// when section of the test
codeUnderTest()
}
```
---
#### Constants
- Reusable values are extracted to file level immutable properties or constants.
- These can be parameters or expected results.
- The naming convention is to prefix with `A` or `AN` for better matching with the test name.
```kotlin
private const val A_LOWERCASE_LABEL = "hello"
class MyTest {
@Test
fun `when uppercasing a lowercase label, then returns label uppercased`() {
val result = TextUppercaser().uppercase(A_LOWERCASE_LABEL)
...
}
}
```
---
#### Mocking
- In order to provide different behaviour for dependencies within tests our main method is through mocking, using [Mockk](https://mockk.io/).
- We avoid using relaxed mocks in favour of explicitly declaring mock behaviour through the _Fake_ convention. There are exceptions when mocking framework
classes which would require a lot of boilerplate.
- Using `Spy` is discouraged as it inherently requires real instances, which we are avoiding in our tests. There are exceptions such as `VectorFeatures` which
acts like a `Fixture` in release builds.
---
#### Fakes
- Fakes are reusable instances of classes purely for testing purposes. They provide functions to replace the functions of the interface/class they're faking
with test specific values.
- When faking an interface, the _Fake_ can be written using delegation or by stubbing
- All Fakes currently reside in the same package `${package}.test.fakes`
```kotlin
// Delegating to a mock
class FakeClock : Clock by mockk() {
fun givenEpoch(epoch: Long) {
every { epochMillis() } returns epoch
}
}
// Stubbing the interface
class FakeClock(private val epoch: Long) : Clock {
override fun epochMillis() = epoch
}
```
It's currently more common for fakes to fake class behaviour, we achieve this by wrapping and exposing a mock instance.
```kotlin
class FakeCursor {
val instance = mockk<Cursor>()
fun givenEmpty() {
every { instance.count } returns 0
every { instance.moveToFirst() } returns false
}
}
val fakeCursor = FakeCursor().apply { givenEmpty() }
```
#### Fixtures
- Fixtures are a reusable wrappers around data models. They provide default values to make creating instances as easy as possible, with the option to override
specific parameters when needed.
- Are namespaced within an `object`.
- Reduces the _find usages_ noise when searching for usages of the origin class construction.
- All Fixtures currently reside in the same package `${package}.test.fixtures`.
```kotlin
object ContentAttachmentDataFixture {
fun aContentAttachmentData(
type: ContentAttachmentData.Type.TEXT,
mimeType: String? = null
) = ContentAttachmentData(type, mimeType)
}
```
- Fixtures can also be used to manage specific combinations of parameters
```kotlin
fun aContentAttachmentAudioData() = aContentAttachmentData(
type = ContentAttachmentData.Type.AUDIO,
mimeType = "audio/mp3",
)
```
---
### Examples
##### Extensions used to streamline the test setup
```kotlin
class CircularCacheTest {
@Test
fun `when putting more than cache size then cache is limited to cache size`() {
val (cache, internalData) = createIntCache(cacheSize = 3)
cache.putInOrder(1, 1, 1, 1, 1, 1)
internalData shouldBeEqualTo arrayOf(1, 1, 1)
}
}
private fun createIntCache(cacheSize: Int): Pair<CircularCache<Int>, Array<Int?>> {
var internalData: Array<Int?>? = null
val factory: (Int) -> Array<Int?> = {
Array<Int?>(it) { null }.also { array -> internalData = array }
}
return CircularCache(cacheSize, factory) to internalData!!
}
private fun CircularCache<Int>.putInOrder(vararg values: Int) {
values.forEach { put(it) }
}
```
##### Fakes and Fixtures
```kotlin
class LateInitUserPropertiesFactoryTest {
private val fakeActiveSessionDataSource = FakeActiveSessionDataSource()
private val fakeVectorStore = FakeVectorStore()
private val fakeContext = FakeContext()
private val fakeSession = FakeSession().also {
it.givenVectorStore(fakeVectorStore.instance)
}
private val lateInitUserProperties = LateInitUserPropertiesFactory(
fakeActiveSessionDataSource.instance,
fakeContext.instance
)
@Test
fun `given no active session, when creating properties, then returns null`() {
val result = lateInitUserProperties.createUserProperties()
result shouldBeEqualTo null
}
@Test
fun `given a teams use case set on an active session, when creating properties, then includes the remapped WorkMessaging selection`() {
fakeVectorStore.givenUseCase(FtueUseCase.TEAMS)
fakeActiveSessionDataSource.setActiveSession(fakeSession)
val result = lateInitUserProperties.createUserProperties()
result shouldBeEqualTo UserProperties(
ftueUseCaseSelection = UserProperties.FtueUseCaseSelection.WorkMessaging
)
}
}
```
##### ViewModel
- `ViewModels` tend to be one of the most complex areas to unit test due to their position as a coordinator of data flows and bridge between domains.
- As the project uses a slightly tweaked`MvRx`, our API for the `ViewModel` is simplified down to `input - ViewModel.handle(Action)`
and `output Flows - ViewModel.viewEvents & ViewModel.stateFlow`. A `ViewModel` test asserter has been created to further simplify the process.
```kotlin
class ViewModelTest {
private var initialState = ViewState.Empty
@get:Rule
val mavericksTestRule = MavericksTestRule(testDispatcher = UnconfinedTestDispatcher())
@Test
fun `when handling MyAction, then emits Loading and Content states`() {
val viewModel = ViewModel<State>(initialState)
val test = viewModel.test() // must be invoked before interacting with the VM
viewModel.handle(MyAction)
test
.assertViewStates(initialState, State.Loading, State.Content())
.assertNoEvents()
.finish()
}
}
```
- `ViewModels` often emit multiple states which are copies of the previous state, the `test` extension `assertStatesChanges` allows only the difference to be
supplied.
```kotlin
data class ViewState(val name: String? = null, val age: Int? = null)
val initialState = ViewState()
val viewModel = ViewModel<State>(initialState)
val test = viewModel.test()
viewModel.handle(ChangeNameAction("Gandalf"))
test
.assertStatesChanges(
initialState,
{ copy(name = "Gandalf") },
)
.finish()
```

View file

@ -1,49 +1,64 @@
fastlane documentation
================
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```
```sh
xcode-select --install
```
Install _fastlane_ using
```
[sudo] gem install fastlane -NV
```
or alternatively using `brew install fastlane`
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## Android
### android test
```sh
[bundle exec] fastlane android test
```
fastlane android test
```
Runs all the tests
### android beta
```sh
[bundle exec] fastlane android beta
```
fastlane android beta
```
Submit a new Beta Build to Crashlytics Beta
### android deploy
```sh
[bundle exec] fastlane android deploy
```
fastlane android deploy
```
Deploy a new version to the Google Play
### android deployMeta
```sh
[bundle exec] fastlane android deployMeta
```
fastlane android deployMeta
```
Deploy Google Play metadata
### android getVersionCode
```sh
[bundle exec] fastlane android getVersionCode
```
fastlane android getVersionCode
```
Get version code
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View file

@ -1 +1 @@
مُحادثة آمنة لا مركزية و VoIP. حافظ على بياناتك آمنة من الأطراف الثالثة.
برنامج المراسلة الجماعية - الرسائل المشفرة والدردشة الجماعية ومكالمات الفيديو

View file

@ -1 +1 @@
Element (Riot.im سابقًا)
إيليمنت - تطبيق محادثات أمن

View file

@ -0,0 +1 @@
Qrup mesajlaşma - şifrəli mesajlaşma, qrup söhbəti və video zənglər

View file

@ -0,0 +1 @@
Element

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Podpora UnifiedPush a možnost používat push bez FCM.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Umožňuje vylepšené přihlašování a registraci.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Umožňuje vylepšené přihlašování a registraci.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,3 @@
Nový vzhled aplikace lze povolit v Experimentálních funkcích. Prosíme, vyzkoušejte ho!
Oprava problémů s chybějícími oznámeními a dlouhou přírůstkovou synchronizací.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Odložené přímé zprávy jsou ve výchozím nastavení povoleny.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Nové rozvržení aplikace je povoleno ve výchozím nastavení!
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Nové funkce v Experimentálních funkcích: Rozšířený editor zpráv, nová správa zařízení, hlasové vysílání. Stále v aktivním vývoji!
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: nové uživatelské rozhraní pro výběr přílohy.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: nové uživatelské rozhraní pro výběr přílohy.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: opravy různých chyb a vylepšení.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Nová implementace celoobrazovkového režimu pro editor formátovaného textu a opravy chyb.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Nová implementace celoobrazovkového režimu pro editor formátovaného textu a opravy chyb.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Vlákna jsou nyní ve výchozím nastavení povolena.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Především opravy chyb!
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Především vylepšení funkce hlasového vysílání.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Verbesserte Verwaltung der ignorierten Benutzer:innen. Verschiedene Fehlerbehebungen und Stabilitätsverbesserungen.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Bessere Verwaltung von verschlüsselten Nachrichten. Verschiedene Fehlerbehebungen und Stabilitätsverbesserungen.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Verschiedene Fehlerbehebungen und Stabilitätsverbesserungen.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View file

@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Verschiedene Fehlerbehebungen und Stabilitätsverbesserungen.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

Some files were not shown because too many files have changed in this diff Show more