From cd45248f402699ab7970520123468555d7918ee0 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 12 Mar 2022 09:32:25 +0100 Subject: [PATCH 001/349] Fix modifying the wrong events in TimelineChunk I was observing cases where builtEvents[modificationIndex] was not having the same eventId as the udpatedEntity in handleDatabaseChangeSet. In particular, I observed both cases that - there was no item in the list yet with the same eventId as the updated one - there was an item with the same eventId already in the list, but at a different position. Whenever this happened, the timeline would render missing, duplicated, or swapped messages in the timeline. Instead of relying on the modificationIndex to be the same for both the change set and builtEvents, look up the proper index by eventId. --- changelog.d/5528.bugfix | 1 + .../sdk/internal/session/room/timeline/TimelineChunk.kt | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5528.bugfix diff --git a/changelog.d/5528.bugfix b/changelog.d/5528.bugfix new file mode 100644 index 0000000000..b0dc759ab0 --- /dev/null +++ b/changelog.d/5528.bugfix @@ -0,0 +1 @@ +Fix cases of missing, swapped, or duplicated messages diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 77f210aa9a..472cda39f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -447,8 +447,12 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, for (range in modifications) { for (modificationIndex in (range.startIndex until range.startIndex + range.length)) { val updatedEntity = results[modificationIndex] ?: continue + val displayIndex = builtEventsIndexes.getOrDefault(updatedEntity.eventId, null) + if (displayIndex == null) { + continue + } try { - builtEvents[modificationIndex] = updatedEntity.buildAndDecryptIfNeeded() + builtEvents[displayIndex] = updatedEntity.buildAndDecryptIfNeeded() } catch (failure: Throwable) { Timber.v("Fail to update items at index: $modificationIndex") } From 626395304db6f0818cbfa337ed469a47e4684642 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 19 Mar 2022 11:51:19 +0100 Subject: [PATCH 002/349] Fix crash on Android 6 --- .../android/sdk/internal/session/room/timeline/TimelineChunk.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 472cda39f8..368979d73e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -447,7 +447,7 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, for (range in modifications) { for (modificationIndex in (range.startIndex until range.startIndex + range.length)) { val updatedEntity = results[modificationIndex] ?: continue - val displayIndex = builtEventsIndexes.getOrDefault(updatedEntity.eventId, null) + val displayIndex = builtEventsIndexes[updatedEntity.eventId] if (displayIndex == null) { continue } From 6a8230239b13b52d6b2622afdffd4d56726964c3 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Mon, 21 Mar 2022 10:46:59 +0100 Subject: [PATCH 003/349] Avoid inconsistent timelines by db insertions before fully loaded chunk --- .../session/room/timeline/TimelineChunk.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 368979d73e..1bd541c2a9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -430,6 +430,31 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, private fun handleDatabaseChangeSet(results: RealmResults, changeSet: OrderedCollectionChangeSet) { val insertions = changeSet.insertionRanges for (range in insertions) { + // Check if the insertion's displayIndices match our expectations - or skip this insertion. + // Inconsistencies (missing messages) can happen otherwise if we get insertions before having loaded all timeline events of the chunk. + if (builtEvents.isNotEmpty()) { + // Check consistency to item before insertions + if (range.startIndex > 0) { + val firstInsertion = results[range.startIndex]!! + val lastBeforeInsertion = builtEvents[range.startIndex-1] + if (firstInsertion.displayIndex+1 != lastBeforeInsertion.displayIndex) { + Timber.i("handleDatabaseChangeSet: skip insertion at ${range.startIndex}/${builtEvents.size}, " + + "displayIndex mismatch at ${range.startIndex}: ${firstInsertion.displayIndex} -> ${lastBeforeInsertion.displayIndex}") + continue + } + } + // Check consistency to item after insertions + if (range.startIndex < builtEvents.size) { + val lastInsertion = results[range.startIndex+range.length-1]!! + val firstAfterInsertion = builtEvents[range.startIndex] + if (firstAfterInsertion.displayIndex+1 != lastInsertion.displayIndex) { + Timber.i("handleDatabaseChangeSet: skip insertion at ${range.startIndex}/${builtEvents.size}, " + + "displayIndex mismatch at ${range.startIndex+range.length}: " + + "${firstAfterInsertion.displayIndex} -> ${lastInsertion.displayIndex}") + continue + } + } + } val newItems = results .subList(range.startIndex, range.startIndex + range.length) .map { it.buildAndDecryptIfNeeded() } From 7c0cd1dc52e3ebb6f7b8be65a8da93f837b175f0 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Tue, 12 Apr 2022 19:16:48 +0200 Subject: [PATCH 004/349] Fix ktLint / op-spacing --- .../internal/session/room/timeline/TimelineChunk.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 1bd541c2a9..db90343422 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -436,8 +436,8 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, // Check consistency to item before insertions if (range.startIndex > 0) { val firstInsertion = results[range.startIndex]!! - val lastBeforeInsertion = builtEvents[range.startIndex-1] - if (firstInsertion.displayIndex+1 != lastBeforeInsertion.displayIndex) { + val lastBeforeInsertion = builtEvents[range.startIndex - 1] + if (firstInsertion.displayIndex + 1 != lastBeforeInsertion.displayIndex) { Timber.i("handleDatabaseChangeSet: skip insertion at ${range.startIndex}/${builtEvents.size}, " + "displayIndex mismatch at ${range.startIndex}: ${firstInsertion.displayIndex} -> ${lastBeforeInsertion.displayIndex}") continue @@ -445,11 +445,11 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, } // Check consistency to item after insertions if (range.startIndex < builtEvents.size) { - val lastInsertion = results[range.startIndex+range.length-1]!! + val lastInsertion = results[range.startIndex + range.length - 1]!! val firstAfterInsertion = builtEvents[range.startIndex] - if (firstAfterInsertion.displayIndex+1 != lastInsertion.displayIndex) { + if (firstAfterInsertion.displayIndex + 1 != lastInsertion.displayIndex) { Timber.i("handleDatabaseChangeSet: skip insertion at ${range.startIndex}/${builtEvents.size}, " + - "displayIndex mismatch at ${range.startIndex+range.length}: " + + "displayIndex mismatch at ${range.startIndex + range.length}: " + "${firstAfterInsertion.displayIndex} -> ${lastInsertion.displayIndex}") continue } From a8bbf29b426b66b4c5f9c21fbc192310f799f207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Fri, 15 Apr 2022 22:50:54 +0200 Subject: [PATCH 005/349] Remove unused dependencies --- build.gradle | 17 +++++++++++++++++ dependencies.gradle | 2 +- library/attachment-viewer/build.gradle | 6 ++++-- library/core-utils/build.gradle | 3 +-- library/multipicker/build.gradle | 2 +- library/ui-styles/build.gradle | 6 +----- matrix-sdk-android-flow/build.gradle | 5 ----- matrix-sdk-android/build.gradle | 10 +--------- vector/build.gradle | 3 --- 9 files changed, 26 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index 1ff1da7427..6cbc11351e 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,7 @@ buildscript { // ktlint Plugin plugins { id "org.jlleitschuh.gradle.ktlint" version "10.2.1" + id 'com.autonomousapps.dependency-analysis' version "1.0.0" } // https://github.com/jeremylong/DependencyCheck @@ -193,3 +194,19 @@ project(":library:diff-match-patch") { // } // } //} + +dependencyAnalysis { + dependencies { + bundle("kotlin-stdlib") { + includeGroup("org.jetbrains.kotlin") + } + bundle("react") { + includeGroup("com.facebook.react") + } + } + issues { + all { + ignoreKtx(true) // default is false + } + } +} diff --git a/dependencies.gradle b/dependencies.gradle index 7666a3bf9f..be1b888502 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -81,7 +81,7 @@ ext.libs = [ 'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger" ], squareup : [ - 'moshi' : "com.squareup.moshi:moshi-adapters:$moshi", + 'moshi' : "com.squareup.moshi:moshi:$moshi", 'moshiKotlin' : "com.squareup.moshi:moshi-kotlin-codegen:$moshi", 'retrofit' : "com.squareup.retrofit2:retrofit:$retrofit", 'retrofitMoshi' : "com.squareup.retrofit2:converter-moshi:$retrofit" diff --git a/library/attachment-viewer/build.gradle b/library/attachment-viewer/build.gradle index 048710f62c..b51136a993 100644 --- a/library/attachment-viewer/build.gradle +++ b/library/attachment-viewer/build.gradle @@ -55,5 +55,7 @@ dependencies { implementation libs.androidx.appCompat implementation libs.androidx.recyclerview - implementation libs.google.material -} \ No newline at end of file + api("androidx.viewpager2:viewpager2:1.0.0") + implementation("androidx.core:core:1.7.0") + implementation("androidx.transition:transition:1.2.0") +} diff --git a/library/core-utils/build.gradle b/library/core-utils/build.gradle index ad3a948808..1cc518c432 100644 --- a/library/core-utils/build.gradle +++ b/library/core-utils/build.gradle @@ -50,6 +50,5 @@ android { } dependencies { - implementation libs.androidx.appCompat implementation libs.jetbrains.coroutinesAndroid -} \ No newline at end of file +} diff --git a/library/multipicker/build.gradle b/library/multipicker/build.gradle index bb98a2f852..861238c02b 100644 --- a/library/multipicker/build.gradle +++ b/library/multipicker/build.gradle @@ -39,8 +39,8 @@ android { dependencies { implementation libs.androidx.appCompat - implementation libs.androidx.fragmentKtx implementation libs.androidx.exifinterface + implementation libs.androidx.core // Log implementation libs.jakewharton.timber diff --git a/library/ui-styles/build.gradle b/library/ui-styles/build.gradle index 0ac513b252..debfdf8649 100644 --- a/library/ui-styles/build.gradle +++ b/library/ui-styles/build.gradle @@ -54,10 +54,6 @@ android { dependencies { implementation libs.androidx.appCompat implementation libs.google.material - // Pref theme - implementation libs.androidx.preferenceKtx - // PFLockScreen attrs - implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12' // dialpad dimen implementation 'im.dlg:android-dialer:1.2.5' -} \ No newline at end of file +} diff --git a/matrix-sdk-android-flow/build.gradle b/matrix-sdk-android-flow/build.gradle index ea43ce20c8..fb69af2d82 100644 --- a/matrix-sdk-android-flow/build.gradle +++ b/matrix-sdk-android-flow/build.gradle @@ -31,9 +31,7 @@ android { } dependencies { - implementation project(":matrix-sdk-android") - implementation libs.androidx.appCompat implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid @@ -41,7 +39,4 @@ dependencies { // Paging implementation libs.androidx.pagingRuntimeKtx - - // Logging - implementation libs.jakewharton.timber } diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 0cffa4148e..e9c8804bac 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -109,7 +109,6 @@ dependencies { implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid - implementation libs.androidx.appCompat implementation libs.androidx.core // Lifecycle @@ -128,12 +127,11 @@ dependencies { implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3")) implementation 'com.squareup.okhttp3:okhttp' implementation 'com.squareup.okhttp3:logging-interceptor' - implementation 'com.squareup.okhttp3:okhttp-urlconnection' implementation libs.squareup.moshi kapt libs.squareup.moshiKotlin - implementation libs.markwon.core + api "com.atlassian.commonmark:commonmark:0.13.0" // Image implementation libs.androidx.exifinterface @@ -149,10 +147,6 @@ dependencies { // Work implementation libs.androidx.work - // FP - implementation libs.arrow.core - implementation libs.arrow.instances - // olm lib is now hosted in MavenCentral implementation 'org.matrix.android:olm-sdk:3.2.10' @@ -174,8 +168,6 @@ dependencies { implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.46' testImplementation libs.tests.junit - testImplementation 'org.robolectric:robolectric:4.7.3' - //testImplementation 'org.robolectric:shadows-support-v4:3.0' // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281 testImplementation libs.mockk.mockk testImplementation libs.tests.kluent diff --git a/vector/build.gradle b/vector/build.gradle index c7950da28e..237754d2d1 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -6,7 +6,6 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-kapt' apply plugin: 'com.likethesalad.stem' -apply plugin: 'dagger.hilt.android.plugin' kapt { correctErrorTypes = true @@ -373,7 +372,6 @@ dependencies { // FlowBinding implementation libs.github.flowBinding implementation libs.github.flowBindingAppcompat - implementation libs.github.flowBindingMaterial implementation libs.airbnb.epoxy implementation libs.airbnb.epoxyGlide @@ -448,7 +446,6 @@ dependencies { implementation 'com.github.jetradarmobile:android-snowfall:1.2.1' // DI implementation libs.dagger.hilt - kapt libs.dagger.hiltCompiler // Analytics implementation 'com.posthog.android:posthog:1.1.2' From b3cfc88773075b3ef64ca89ed3fa18708eff10b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Fri, 15 Apr 2022 23:36:42 +0200 Subject: [PATCH 006/349] Fix androidTest --- library/attachment-viewer/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/attachment-viewer/build.gradle b/library/attachment-viewer/build.gradle index b51136a993..b89d9c6cca 100644 --- a/library/attachment-viewer/build.gradle +++ b/library/attachment-viewer/build.gradle @@ -55,7 +55,5 @@ dependencies { implementation libs.androidx.appCompat implementation libs.androidx.recyclerview - api("androidx.viewpager2:viewpager2:1.0.0") - implementation("androidx.core:core:1.7.0") - implementation("androidx.transition:transition:1.2.0") + implementation libs.google.material } From cdd7db417409bac50ff24db741dcdc80c963219e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sat, 16 Apr 2022 09:40:15 +0200 Subject: [PATCH 007/349] Fix unused resource references properly --- library/attachment-viewer/build.gradle | 3 ++- .../src/main/res/values/styles_pin_code.xml | 14 +------------- .../ui-styles/src/main/res/values/theme_dark.xml | 11 ----------- .../ui-styles/src/main/res/values/theme_light.xml | 11 ----------- 4 files changed, 3 insertions(+), 36 deletions(-) diff --git a/library/attachment-viewer/build.gradle b/library/attachment-viewer/build.gradle index b89d9c6cca..57e5f30887 100644 --- a/library/attachment-viewer/build.gradle +++ b/library/attachment-viewer/build.gradle @@ -55,5 +55,6 @@ dependencies { implementation libs.androidx.appCompat implementation libs.androidx.recyclerview - implementation libs.google.material + api "androidx.viewpager2:viewpager2:1.0.0" + implementation "androidx.transition:transition:1.2.0" } diff --git a/library/ui-styles/src/main/res/values/styles_pin_code.xml b/library/ui-styles/src/main/res/values/styles_pin_code.xml index 2b6c113359..edec029faf 100644 --- a/library/ui-styles/src/main/res/values/styles_pin_code.xml +++ b/library/ui-styles/src/main/res/values/styles_pin_code.xml @@ -21,18 +21,6 @@ 24dp - - - - @@ -41,4 +29,4 @@ ?vctr_content_primary - \ No newline at end of file + diff --git a/library/ui-styles/src/main/res/values/theme_dark.xml b/library/ui-styles/src/main/res/values/theme_dark.xml index 7177687fdd..185e5b919c 100644 --- a/library/ui-styles/src/main/res/values/theme_dark.xml +++ b/library/ui-styles/src/main/res/values/theme_dark.xml @@ -106,17 +106,6 @@ never - @style/PreferenceThemeOverlay.v14.Material - - @style/PinCodeScreenStyle - @style/PinCodeKeyButtonStyle - @style/PinCodeTitleStyle - @style/PinCodeHintStyle - @style/PinCodeDotsViewStyle - @style/PinCodeDeleteButtonStyle - @style/PinCodeFingerprintButtonStyle - @style/PinCodeNextButtonStyle - @color/android_status_bar_background_dark @color/android_navigation_bar_background_dark diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml index c90c021591..0eb11a139c 100644 --- a/library/ui-styles/src/main/res/values/theme_light.xml +++ b/library/ui-styles/src/main/res/values/theme_light.xml @@ -106,17 +106,6 @@ never - @style/PreferenceThemeOverlay.v14.Material - - @style/PinCodeScreenStyle - @style/PinCodeKeyButtonStyle - @style/PinCodeTitleStyle - @style/PinCodeHintStyle - @style/PinCodeDotsViewStyle - @style/PinCodeDeleteButtonStyle - @style/PinCodeFingerprintButtonStyle - @style/PinCodeNextButtonStyle - @color/android_status_bar_background_dark From 2138ec07992af8f153367daaaf937d8d7847fdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sat, 16 Apr 2022 11:14:04 +0200 Subject: [PATCH 008/349] Remove unused resource to make lint happy --- .../ui-styles/src/main/res/drawable/bg_pin_key.xml | 13 ------------- .../src/main/res/values/styles_pin_code.xml | 6 ------ 2 files changed, 19 deletions(-) delete mode 100644 library/ui-styles/src/main/res/drawable/bg_pin_key.xml diff --git a/library/ui-styles/src/main/res/drawable/bg_pin_key.xml b/library/ui-styles/src/main/res/drawable/bg_pin_key.xml deleted file mode 100644 index d4a54577be..0000000000 --- a/library/ui-styles/src/main/res/drawable/bg_pin_key.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/library/ui-styles/src/main/res/values/styles_pin_code.xml b/library/ui-styles/src/main/res/values/styles_pin_code.xml index edec029faf..c69819f7ba 100644 --- a/library/ui-styles/src/main/res/values/styles_pin_code.xml +++ b/library/ui-styles/src/main/res/values/styles_pin_code.xml @@ -5,12 +5,6 @@ ?android:colorBackground - - From 4305b21ba85a785c2947784a1ea46f88a69facf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sat, 16 Apr 2022 20:36:43 +0200 Subject: [PATCH 009/349] Remove unused resource to make lint happy --- .../main/res/drawable/pin_code_dot_empty.xml | 13 ---------- .../main/res/drawable/pin_code_dot_fill.xml | 12 --------- .../src/main/res/drawable/pin_code_dots.xml | 9 ------- .../src/main/res/values/styles_pin_code.xml | 26 ------------------- 4 files changed, 60 deletions(-) delete mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml delete mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml delete mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dots.xml delete mode 100644 library/ui-styles/src/main/res/values/styles_pin_code.xml diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml b/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml deleted file mode 100644 index 1827a7682b..0000000000 --- a/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml b/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml deleted file mode 100644 index 799ea30174..0000000000 --- a/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dots.xml b/library/ui-styles/src/main/res/drawable/pin_code_dots.xml deleted file mode 100644 index 29e445e511..0000000000 --- a/library/ui-styles/src/main/res/drawable/pin_code_dots.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/library/ui-styles/src/main/res/values/styles_pin_code.xml b/library/ui-styles/src/main/res/values/styles_pin_code.xml deleted file mode 100644 index c69819f7ba..0000000000 --- a/library/ui-styles/src/main/res/values/styles_pin_code.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - From 2c84f234a600eedca62b37e9dd63f994da758401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sun, 17 Apr 2022 11:09:10 +0200 Subject: [PATCH 010/349] Cleanup --- dependencies.gradle | 5 ++++- library/attachment-viewer/build.gradle | 4 ++-- library/multipicker/build.gradle | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index be1b888502..ec27184d5c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -45,6 +45,7 @@ ext.libs = [ 'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines" ], androidx : [ + 'activity' : "androidx.activity:activity:1.2.4", 'appCompat' : "androidx.appcompat:appcompat:1.4.0", 'core' : "androidx.core:core-ktx:1.7.0", 'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1", @@ -69,7 +70,9 @@ ext.libs = [ 'testRules' : "androidx.test:rules:$androidxTest", 'espressoCore' : "androidx.test.espresso:espresso-core:$espresso", 'espressoContrib' : "androidx.test.espresso:espresso-contrib:$espresso", - 'espressoIntents' : "androidx.test.espresso:espresso-intents:$espresso" + 'espressoIntents' : "androidx.test.espresso:espresso-intents:$espresso", + 'viewpager2' : "androidx.viewpager2:viewpager2:1.0.0", + 'transition' : "androidx.transition:transition:1.2.0", ], google : [ 'material' : "com.google.android.material:material:1.5.0" diff --git a/library/attachment-viewer/build.gradle b/library/attachment-viewer/build.gradle index 57e5f30887..8bbafd3387 100644 --- a/library/attachment-viewer/build.gradle +++ b/library/attachment-viewer/build.gradle @@ -55,6 +55,6 @@ dependencies { implementation libs.androidx.appCompat implementation libs.androidx.recyclerview - api "androidx.viewpager2:viewpager2:1.0.0" - implementation "androidx.transition:transition:1.2.0" + api libs.androidx.viewpager2 + implementation libs.androidx.transition } diff --git a/library/multipicker/build.gradle b/library/multipicker/build.gradle index 861238c02b..2de99d5c20 100644 --- a/library/multipicker/build.gradle +++ b/library/multipicker/build.gradle @@ -38,7 +38,7 @@ android { } dependencies { - implementation libs.androidx.appCompat + api libs.androidx.activity implementation libs.androidx.exifinterface implementation libs.androidx.core From 2bbecd4cc5d3bf245575ce0816a4f4829ac4f9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sun, 17 Apr 2022 11:35:30 +0200 Subject: [PATCH 011/349] Fix regressions --- library/ui-styles/build.gradle | 4 ++ .../src/main/res/drawable/bg_pin_key.xml | 13 ++++++ .../main/res/drawable/pin_code_dot_empty.xml | 13 ++++++ .../main/res/drawable/pin_code_dot_fill.xml | 12 +++++ .../src/main/res/drawable/pin_code_dots.xml | 9 ++++ .../src/main/res/values/styles_pin_code.xml | 44 +++++++++++++++++++ .../src/main/res/values/theme_dark.xml | 11 +++++ .../src/main/res/values/theme_light.xml | 11 +++++ vector/build.gradle | 2 + 9 files changed, 119 insertions(+) create mode 100644 library/ui-styles/src/main/res/drawable/bg_pin_key.xml create mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml create mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml create mode 100644 library/ui-styles/src/main/res/drawable/pin_code_dots.xml create mode 100644 library/ui-styles/src/main/res/values/styles_pin_code.xml diff --git a/library/ui-styles/build.gradle b/library/ui-styles/build.gradle index debfdf8649..31cfdd24c7 100644 --- a/library/ui-styles/build.gradle +++ b/library/ui-styles/build.gradle @@ -54,6 +54,10 @@ android { dependencies { implementation libs.androidx.appCompat implementation libs.google.material + // Pref theme + implementation libs.androidx.preferenceKtx + // PFLockScreen attrs + implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12' // dialpad dimen implementation 'im.dlg:android-dialer:1.2.5' } diff --git a/library/ui-styles/src/main/res/drawable/bg_pin_key.xml b/library/ui-styles/src/main/res/drawable/bg_pin_key.xml new file mode 100644 index 0000000000..5bf293aab0 --- /dev/null +++ b/library/ui-styles/src/main/res/drawable/bg_pin_key.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml b/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml new file mode 100644 index 0000000000..879cac15ca --- /dev/null +++ b/library/ui-styles/src/main/res/drawable/pin_code_dot_empty.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml b/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml new file mode 100644 index 0000000000..83bdac5126 --- /dev/null +++ b/library/ui-styles/src/main/res/drawable/pin_code_dot_fill.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/library/ui-styles/src/main/res/drawable/pin_code_dots.xml b/library/ui-styles/src/main/res/drawable/pin_code_dots.xml new file mode 100644 index 0000000000..c4b1073f85 --- /dev/null +++ b/library/ui-styles/src/main/res/drawable/pin_code_dots.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/library/ui-styles/src/main/res/values/styles_pin_code.xml b/library/ui-styles/src/main/res/values/styles_pin_code.xml new file mode 100644 index 0000000000..cb22863694 --- /dev/null +++ b/library/ui-styles/src/main/res/values/styles_pin_code.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/library/ui-styles/src/main/res/values/theme_dark.xml b/library/ui-styles/src/main/res/values/theme_dark.xml index 185e5b919c..7177687fdd 100644 --- a/library/ui-styles/src/main/res/values/theme_dark.xml +++ b/library/ui-styles/src/main/res/values/theme_dark.xml @@ -106,6 +106,17 @@ never + @style/PreferenceThemeOverlay.v14.Material + + @style/PinCodeScreenStyle + @style/PinCodeKeyButtonStyle + @style/PinCodeTitleStyle + @style/PinCodeHintStyle + @style/PinCodeDotsViewStyle + @style/PinCodeDeleteButtonStyle + @style/PinCodeFingerprintButtonStyle + @style/PinCodeNextButtonStyle + @color/android_status_bar_background_dark @color/android_navigation_bar_background_dark diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml index 0eb11a139c..c90c021591 100644 --- a/library/ui-styles/src/main/res/values/theme_light.xml +++ b/library/ui-styles/src/main/res/values/theme_light.xml @@ -106,6 +106,17 @@ never + @style/PreferenceThemeOverlay.v14.Material + + @style/PinCodeScreenStyle + @style/PinCodeKeyButtonStyle + @style/PinCodeTitleStyle + @style/PinCodeHintStyle + @style/PinCodeDotsViewStyle + @style/PinCodeDeleteButtonStyle + @style/PinCodeFingerprintButtonStyle + @style/PinCodeNextButtonStyle + @color/android_status_bar_background_dark diff --git a/vector/build.gradle b/vector/build.gradle index 237754d2d1..6d318f82b9 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -6,6 +6,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-kapt' apply plugin: 'com.likethesalad.stem' +apply plugin: 'dagger.hilt.android.plugin' kapt { correctErrorTypes = true @@ -446,6 +447,7 @@ dependencies { implementation 'com.github.jetradarmobile:android-snowfall:1.2.1' // DI implementation libs.dagger.hilt + kapt libs.dagger.hiltCompiler // Analytics implementation 'com.posthog.android:posthog:1.1.2' From 6b9b6880724f18146b1315b5f6d60a9833d8a553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Loipf=C3=BChrer?= Date: Sat, 23 Apr 2022 00:06:18 +0200 Subject: [PATCH 012/349] do not switch away from home space on notification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the preference "Show all Rooms in Home" is selected element should not switch away from the home space when clicking a notification for a room in some other space. With this change one stays in the home space when the said preference is active. fixes #5180 Signed-off-by: Michael Loipführer --- changelog.d/5827.bugfix | 1 + .../vector/app/features/home/room/detail/TimelineViewModel.kt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5827.bugfix diff --git a/changelog.d/5827.bugfix b/changelog.d/5827.bugfix new file mode 100644 index 0000000000..0bd55e33ec --- /dev/null +++ b/changelog.d/5827.bugfix @@ -0,0 +1 @@ +Do not switch away from home space on notification when "Show all Rooms in Home" is selected. diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index b79b55b248..1c55da2656 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -207,7 +207,8 @@ class TimelineViewModel @AssistedInject constructor( appStateHandler.getCurrentRoomGroupingMethod()?.space().let { currentSpace -> val currentRoomSummary = room.roomSummary() ?: return@let // nothing we are good - if (currentSpace == null || !currentRoomSummary.flattenParentIds.contains(currentSpace.roomId)) { + if ((currentSpace == null && !vectorPreferences.prefSpacesShowAllRoomInHome()) + || (currentSpace != null && !currentRoomSummary.flattenParentIds.contains(currentSpace.roomId))) { // take first one or switch to home appStateHandler.setCurrentSpace( currentRoomSummary From 0250f61d10d4a0cb0963d35556d9ae322788d29c Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 26 Apr 2022 15:48:34 +0200 Subject: [PATCH 013/349] Replaces izPublic with isPublic --- .../home/room/list/RoomSummaryItem.kt | 68 ++++++++++++++----- .../home/room/list/RoomSummaryItemFactory.kt | 2 +- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 70c5846646..e5a4e374c9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -45,24 +45,56 @@ import org.matrix.android.sdk.api.util.MatrixItem @EpoxyModelClass(layout = R.layout.item_room) abstract class RoomSummaryItem : VectorEpoxyModel() { - @EpoxyAttribute lateinit var typingMessage: String - @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer - @EpoxyAttribute lateinit var matrixItem: MatrixItem + @EpoxyAttribute + lateinit var typingMessage: String - @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence - @EpoxyAttribute lateinit var lastEventTime: String - @EpoxyAttribute var encryptionTrustLevel: RoomEncryptionTrustLevel? = null - @EpoxyAttribute var userPresence: UserPresence? = null - @EpoxyAttribute var showPresence: Boolean = false - @EpoxyAttribute var izPublic: Boolean = false - @EpoxyAttribute var unreadNotificationCount: Int = 0 - @EpoxyAttribute var hasUnreadMessage: Boolean = false - @EpoxyAttribute var hasDraft: Boolean = false - @EpoxyAttribute var showHighlighted: Boolean = false - @EpoxyAttribute var hasFailedSending: Boolean = false - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: ClickListener? = null - @EpoxyAttribute var showSelected: Boolean = false + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var matrixItem: MatrixItem + + @EpoxyAttribute + lateinit var lastFormattedEvent: EpoxyCharSequence + + @EpoxyAttribute + lateinit var lastEventTime: String + + @EpoxyAttribute + var encryptionTrustLevel: RoomEncryptionTrustLevel? = null + + @EpoxyAttribute + var userPresence: UserPresence? = null + + @EpoxyAttribute + var showPresence: Boolean = false + + @EpoxyAttribute @JvmField + var isPublic: Boolean = false + + @EpoxyAttribute + var unreadNotificationCount: Int = 0 + + @EpoxyAttribute + var hasUnreadMessage: Boolean = false + + @EpoxyAttribute + var hasDraft: Boolean = false + + @EpoxyAttribute + var showHighlighted: Boolean = false + + @EpoxyAttribute + var hasFailedSending: Boolean = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemLongClickListener: View.OnLongClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null + + @EpoxyAttribute + var showSelected: Boolean = false override fun bind(holder: Holder) { super.bind(holder) @@ -79,7 +111,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.draftView.isVisible = hasDraft avatarRenderer.render(matrixItem, holder.avatarImageView) holder.roomAvatarDecorationImageView.render(encryptionTrustLevel) - holder.roomAvatarPublicDecorationImageView.isVisible = izPublic + holder.roomAvatarPublicDecorationImageView.isVisible = isPublic holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.typingView.setTextOrHide(typingMessage) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 6326d9c97a..cd3a8b0890 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -124,7 +124,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .avatarRenderer(avatarRenderer) // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) - .izPublic(roomSummary.isPublic) + .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) .matrixItem(roomSummary.toMatrixItem()) From a3367d4075f54a06f0d7601d3432ad1fef081aea Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 26 Apr 2022 15:48:49 +0200 Subject: [PATCH 014/349] Replaces else cases in when branches to RoomListDisplayMode.FILTERED --- .../features/home/room/list/RoomListFragment.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index aaa469f68d..ef7a1012df 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -204,7 +204,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.isVisible = true RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.isVisible = true RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.isVisible = true - else -> Unit // No button in this mode + RoomListDisplayMode.FILTERED -> Unit // No button in this mode } views.createChatRoomButton.debouncedClicks { @@ -230,7 +230,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.hide() RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.hide() RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.hide() - else -> Unit + RoomListDisplayMode.FILTERED -> Unit } } } @@ -309,7 +309,7 @@ class RoomListFragment @Inject constructor( ) } } - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -330,7 +330,7 @@ class RoomListFragment @Inject constructor( checkEmptyState() } observeItemCount(section, sectionAdapter) - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -359,7 +359,7 @@ class RoomListFragment @Inject constructor( ) } } - section.isExpanded.observe(viewLifecycleOwner) { _ -> + section.isExpanded.observe(viewLifecycleOwner) { refreshCollapseStates() } controller.listener = this @@ -395,7 +395,7 @@ class RoomListFragment @Inject constructor( RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.show() RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.show() RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.show() - else -> Unit + RoomListDisplayMode.FILTERED -> Unit } } } @@ -474,7 +474,8 @@ class RoomListFragment @Inject constructor( StateView.State.Empty( title = getString(R.string.room_list_catchup_empty_title), image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_noun_party_popper), - message = getString(R.string.room_list_catchup_empty_body)) + message = getString(R.string.room_list_catchup_empty_body) + ) } RoomListDisplayMode.PEOPLE -> StateView.State.Empty( @@ -490,7 +491,7 @@ class RoomListFragment @Inject constructor( isBigImage = true, message = getString(R.string.room_list_rooms_empty_body) ) - else -> + RoomListDisplayMode.FILTERED -> // Always display the content in this mode, because if the footer StateView.State.Content } From 45afc044212ffb3a71818f8266c769d3e0d7496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Wed, 27 Apr 2022 20:24:57 +0200 Subject: [PATCH 015/349] Use fixed text size in read receipt counter --- vector/src/main/res/layout/view_read_receipts.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index 907f1ec0e3..e8101ec28d 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -16,6 +16,8 @@ android:paddingStart="4dp" android:paddingEnd="4dp" android:textColor="?vctr_content_primary" + android:textSize="12dp" + tools:ignore="SpUsage" tools:text="999+" /> Date: Wed, 27 Apr 2022 20:34:03 +0200 Subject: [PATCH 016/349] Add changelog --- changelog.d/5856.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5856.bugfix diff --git a/changelog.d/5856.bugfix b/changelog.d/5856.bugfix new file mode 100644 index 0000000000..87f10ac9b2 --- /dev/null +++ b/changelog.d/5856.bugfix @@ -0,0 +1 @@ +Use fixed text size in read receipt counter From 9e53e6cc8f1ef6f0507d93c5961c342185d1a07e Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 10:41:40 +0200 Subject: [PATCH 017/349] Adds space name to rooms in filtered search --- .../relationship/RoomChildRelationInfo.kt | 16 ++-------- .../room/summary/RoomSummaryUpdater.kt | 29 ++++++++----------- .../list/CollapsableTypedEpoxyController.kt | 2 +- .../home/room/list/RoomListFragment.kt | 2 +- .../home/room/list/RoomSummaryItem.kt | 17 ++++++++++- .../home/room/list/RoomSummaryItemFactory.kt | 7 ++++- .../room/list/RoomSummaryListController.kt | 3 +- .../room/list/RoomSummaryPagedController.kt | 6 ++-- .../list/RoomSummaryPagedControllerFactory.kt | 5 ++-- .../features/share/IncomingShareController.kt | 3 +- vector/src/main/res/layout/item_room.xml | 3 +- 11 files changed, 52 insertions(+), 41 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt index 5bad334afc..fffca96acf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relationship/RoomChildRelationInfo.kt @@ -43,7 +43,6 @@ internal class RoomChildRelationInfo( data class SpaceChildInfo( val roomId: String, val order: String?, -// val autoJoin: Boolean, val viaServers: List ) @@ -60,18 +59,13 @@ internal class RoomChildRelationInfo( fun getDirectChildrenDescriptions(): List { return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_CHILD) .findAll() -// .also { -// Timber.v("## Space: Found ${it.count()} m.space.child state events for $roomId") -// } .mapNotNull { ContentMapper.map(it.root?.content).toModel()?.let { scc -> -// Timber.v("## Space child desc state event $scc") // Children where via is not present are ignored. scc.via?.let { via -> SpaceChildInfo( roomId = it.stateKey, order = scc.validOrder(), -// autoJoin = scc.autoJoin ?: false, viaServers = via ) } @@ -83,17 +77,13 @@ internal class RoomChildRelationInfo( fun getParentDescriptions(): List { return CurrentStateEventEntity.whereType(realm, roomId, EventType.STATE_SPACE_PARENT) .findAll() -// .also { -// Timber.v("## Space: Found ${it.count()} m.space.parent state events for $roomId") -// } .mapNotNull { - ContentMapper.map(it.root?.content).toModel()?.let { scc -> -// Timber.v("## Space parent desc state event $scc") + ContentMapper.map(it.root?.content).toModel()?.let { spaceParentContent -> // Parent where via is not present are ignored. - scc.via?.let { via -> + spaceParentContent.via?.let { via -> SpaceParentInfo( roomId = it.stateKey, - canonical = scc.canonical ?: false, + canonical = spaceParentContent.canonical ?: false, viaServers = via, stateEventSender = it.root?.sender ?: "" ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 3af579d050..70c1453865 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm +import io.realm.RealmList import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse @@ -349,39 +350,34 @@ internal class RoomSummaryUpdater @Inject constructor( } val acyclicGraph = graph.withoutEdges(backEdges) -// Timber.v("## SPACES: acyclicGraph $acyclicGraph") val flattenSpaceParents = acyclicGraph.flattenDestination().map { it.key.name to it.value.map { it.name } }.toMap() -// Timber.v("## SPACES: flattenSpaceParents ${flattenSpaceParents.map { it.key.name to it.value.map { it.name } }.joinToString("\n") { -// it.first + ": [" + it.second.joinToString(",") + "]" -// }}") - -// Timber.v("## SPACES: lookup map ${lookupMap.map { it.key.name to it.value.map { it.name } }.toMap()}") lookupMap.entries .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } .forEach { entry -> val parent = RoomSummaryEntity.where(realm, entry.key.roomId).findFirst() if (parent != null) { -// Timber.v("## SPACES: check hierarchy of ${parent.name} id ${parent.roomId}") -// Timber.v("## SPACES: flat known parents of ${parent.name} are ${flattenSpaceParents[parent.roomId]}") val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) -// Timber.v("## SPACES: flatten known parents of children of ${parent.name} are ${flattenParentsIds}") entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> - -// Timber.w("## SPACES: ${childSum.name} is ${childSum.roomId} fc: ${childSum.flattenParentIds}") -// var allParents = childSum.flattenParentIds ?: "" + // TODO: Revisit + childSum.parents.add(SpaceParentSummaryEntity( + true, + parent.roomId, + parent, + RealmList() + )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { - childSum.flattenParentIds += "|$it" + if (childSum.flattenParentIds?.isEmpty() == false) { + childSum.flattenParentIds += "|" + } + childSum.flattenParentIds += it } } -// childSum.flattenParentIds = "$allParents|" - -// Timber.v("## SPACES: flatten of ${childSum.name} is ${childSum.flattenParentIds}") } } } @@ -411,7 +407,6 @@ internal class RoomSummaryUpdater @Inject constructor( // we keep real m.child/m.parent relations and add the one for common memberships dmRoom.flattenParentIds += "|${flattenRelated.joinToString("|")}|" } -// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}") } // Maybe a good place to count the number of notifications for spaces? diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt index 8cf7e6bcab..35396d52d5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/CollapsableTypedEpoxyController.kt @@ -68,7 +68,7 @@ abstract class CollapsableTypedEpoxyController : } override fun buildModels() { - check(isBuildingModels()) { + check(isBuildingModels) { ("You cannot call `buildModels` directly. Call `setData` instead to trigger a model " + "refresh with new data.") } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index ef7a1012df..cabaf11b75 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -287,7 +287,7 @@ class RoomListFragment @Inject constructor( val contentAdapter = when { section.livePages != null -> { - pagedControllerFactory.createRoomSummaryPagedController() + pagedControllerFactory.createRoomSummaryPagedController(roomListParams.displayMode) .also { controller -> section.livePages.observe(viewLifecycleOwner) { pl -> controller.submitList(pl) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index e5a4e374c9..a869041aa8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -36,6 +36,7 @@ import im.vector.app.core.ui.views.PresenceStateImageView import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.themes.ThemeUtils import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel @@ -54,6 +55,12 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var matrixItem: MatrixItem + @EpoxyAttribute + var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE + + @EpoxyAttribute + var spaceName: String? = null + @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence @@ -105,7 +112,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { } holder.titleView.text = matrixItem.getBestName() holder.lastEventTimeView.text = lastEventTime - holder.lastEventView.text = lastFormattedEvent.charSequence + holder.lastEventView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -119,6 +126,14 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarPresenceImageView.render(showPresence, userPresence) } + private fun getTextForLastEventView(): CharSequence { + return if (displayMode == RoomListDisplayMode.FILTERED) { + spaceName.orEmpty() // TODO: handle other cases + } else { + lastFormattedEvent.charSequence + } + } + override fun unbind(holder: Holder) { holder.rootView.setOnClickListener(null) holder.rootView.setOnLongClickListener(null) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index cd3a8b0890..f11f39e402 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -26,6 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter import im.vector.app.features.home.room.typing.TypingHelper import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence @@ -46,13 +47,14 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor fun create(roomSummary: RoomSummary, roomChangeMembershipStates: Map, selectedRoomIds: Set, + displayMode: RoomListDisplayMode, listener: RoomListListener?): VectorEpoxyModel<*> { return when (roomSummary.membership) { Membership.INVITE -> { val changeMembershipState = roomChangeMembershipStates[roomSummary.roomId] ?: ChangeMembershipState.Unknown createInvitationItem(roomSummary, changeMembershipState, listener) } - else -> createRoomItem(roomSummary, selectedRoomIds, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) + else -> createRoomItem(roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) } } @@ -105,6 +107,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor fun createRoomItem( roomSummary: RoomSummary, selectedRoomIds: Set, + displayMode: RoomListDisplayMode, onClick: ((RoomSummary) -> Unit)?, onLongClick: ((RoomSummary) -> Boolean)? ): VectorEpoxyModel<*> { @@ -124,6 +127,8 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor .avatarRenderer(avatarRenderer) // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .spaceName(roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name.orEmpty()) .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt index 75aaee45cb..683263dbbc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.list +import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryListController( @@ -26,7 +27,7 @@ class RoomSummaryListController( override fun buildModels(data: List?) { data?.forEach { - add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), listener)) + add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), RoomListDisplayMode.ROOMS /* TODO: change */, listener)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt index e9cbc69215..445438eec9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt @@ -19,11 +19,13 @@ package im.vector.app.features.home.room.list import com.airbnb.epoxy.EpoxyModel import com.airbnb.epoxy.paging.PagedListEpoxyController import im.vector.app.core.utils.createUIHandler +import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryPagedController( - private val roomSummaryItemFactory: RoomSummaryItemFactory + private val roomSummaryItemFactory: RoomSummaryItemFactory, + private val displayMode: RoomListDisplayMode ) : PagedListEpoxyController( // Important it must match the PageList builder notify Looper modelBuildingHandler = createUIHandler() @@ -57,6 +59,6 @@ class RoomSummaryPagedController( override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> { // for place holder if enabled item ?: return RoomSummaryItemPlaceHolder_().apply { id(currentPosition) } - return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), listener) + return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), displayMode, listener) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt index c86d8ab243..36f1b5ac90 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt @@ -16,14 +16,15 @@ package im.vector.app.features.home.room.list +import im.vector.app.features.home.RoomListDisplayMode import javax.inject.Inject class RoomSummaryPagedControllerFactory @Inject constructor( private val roomSummaryItemFactory: RoomSummaryItemFactory ) { - fun createRoomSummaryPagedController(): RoomSummaryPagedController { - return RoomSummaryPagedController(roomSummaryItemFactory) + fun createRoomSummaryPagedController(displayMode: RoomListDisplayMode): RoomSummaryPagedController { + return RoomSummaryPagedController(roomSummaryItemFactory, displayMode) } fun createRoomSummaryListController(): RoomSummaryListController { diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index fd35bf11a4..7c82b7aea0 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -22,6 +22,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.resources.StringProvider +import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.RoomSummaryItemFactory import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject @@ -53,7 +54,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac } else { roomSummaries.forEach { roomSummary -> roomSummaryItemFactory - .createRoomItem(roomSummary, data.selectedRoomIds, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) + .createRoomItem(roomSummary, data.selectedRoomIds, RoomListDisplayMode.ROOMS /* TODO: Change */, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) .addTo(this) } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 2b27cb8efe..3911e8df34 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -213,7 +213,8 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/roomNameView" app:layout_constraintTop_toBottomOf="@id/roomNameView" - tools:text="Alice is typing…" /> + tools:text="Alice is typing…" + tools:visibility="gone" /> Date: Thu, 28 Apr 2022 11:12:47 +0200 Subject: [PATCH 018/349] Adds user id and canonical alias to search result subtitles --- .../app/features/home/room/list/RoomSummaryItem.kt | 10 +++++----- .../home/room/list/RoomSummaryItemFactory.kt | 12 +++++++++++- vector/src/main/res/layout/item_room.xml | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index a869041aa8..3c091d0e05 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -59,7 +59,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE @EpoxyAttribute - var spaceName: String? = null + lateinit var subtitle: String @EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence @@ -112,7 +112,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { } holder.titleView.text = matrixItem.getBestName() holder.lastEventTimeView.text = lastEventTime - holder.lastEventView.text = getTextForLastEventView() + holder.subtitleView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -122,13 +122,13 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.typingView.setTextOrHide(typingMessage) - holder.lastEventView.isInvisible = holder.typingView.isVisible + holder.subtitleView.isInvisible = holder.typingView.isVisible holder.roomAvatarPresenceImageView.render(showPresence, userPresence) } private fun getTextForLastEventView(): CharSequence { return if (displayMode == RoomListDisplayMode.FILTERED) { - spaceName.orEmpty() // TODO: handle other cases + subtitle } else { lastFormattedEvent.charSequence } @@ -157,7 +157,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val titleView by bind(R.id.roomNameView) val unreadCounterBadgeView by bind(R.id.roomUnreadCounterBadgeView) val unreadIndentIndicator by bind(R.id.roomUnreadIndicator) - val lastEventView by bind(R.id.roomLastEventView) + val subtitleView by bind(R.id.subtitleView) val typingView by bind(R.id.roomTypingView) val draftView by bind(R.id.roomDraftBadge) val lastEventTimeView by bind(R.id.roomLastEventTimeView) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index f11f39e402..cc99c0eb6e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -111,6 +111,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor onClick: ((RoomSummary) -> Unit)?, onLongClick: ((RoomSummary) -> Boolean)? ): VectorEpoxyModel<*> { + val subtitle = getSearchResultSubtitle(roomSummary) val unreadCount = roomSummary.notificationCount val showHighlighted = roomSummary.highlightCount > 0 val showSelected = selectedRoomIds.contains(roomSummary.roomId) @@ -121,6 +122,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect, roomSummary.isDirect.not()) latestEventTime = dateFormatter.format(latestEvent.root.originServerTs, DateFormatKind.ROOM_LIST) } + val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers) return RoomSummaryItem_() .id(roomSummary.roomId) @@ -128,7 +130,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) .displayMode(displayMode) - .spaceName(roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name.orEmpty()) + .subtitle(subtitle) .isPublic(roomSummary.isPublic) .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) @@ -147,4 +149,12 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } .itemClickListener { onClick?.invoke(roomSummary) } } + + private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { + val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name + val userId = roomSummary.directUserId + val canonicalAlias = roomSummary.canonicalAlias + + return (spaceName ?: userId ?: canonicalAlias).orEmpty() + } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 3911e8df34..ab0af18acb 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -183,7 +183,7 @@ tools:text="@tools:sample/date/hhmm" /> Date: Thu, 28 Apr 2022 11:46:02 +0200 Subject: [PATCH 019/349] Disables typing indicator in filtered search --- .../app/features/home/room/list/RoomSummaryItem.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 3c091d0e05..e0547b87b1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -121,9 +121,16 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarPublicDecorationImageView.isVisible = isPublic holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible holder.roomAvatarPresenceImageView.render(showPresence, userPresence) + showTypingViewIfNecessary(holder) + + } + + private fun showTypingViewIfNecessary(holder: Holder) { + if (displayMode != RoomListDisplayMode.FILTERED) { + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible + } } private fun getTextForLastEventView(): CharSequence { From 33475602f865d339c3119cb7e137c5c02aa4e9c5 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 11:54:51 +0200 Subject: [PATCH 020/349] Adds canonical named argument to RoomSummaryUpdater --- .../sdk/internal/session/room/summary/RoomSummaryUpdater.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 70c1453865..1c1963bfd4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -364,7 +364,7 @@ internal class RoomSummaryUpdater @Inject constructor( RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> // TODO: Revisit childSum.parents.add(SpaceParentSummaryEntity( - true, + canonical = true, parent.roomId, parent, RealmList() From b28035807788e1ac40a1586a24b2a9b79046c4c7 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 11:55:44 +0200 Subject: [PATCH 021/349] Adds more named arguments to RoomSummaryUpdater --- .../sdk/internal/session/room/summary/RoomSummaryUpdater.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 1c1963bfd4..81979c6926 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -365,9 +365,9 @@ internal class RoomSummaryUpdater @Inject constructor( // TODO: Revisit childSum.parents.add(SpaceParentSummaryEntity( canonical = true, - parent.roomId, - parent, - RealmList() + parentRoomId = parent.roomId, + parentSummaryEntity = parent, + viaServers = RealmList() )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { From 4784717b0cecab67d03731daaa4dc32f58ef8e1d Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:02:04 +0200 Subject: [PATCH 022/349] Fixes lint error --- .../im/vector/app/features/home/room/list/RoomSummaryItem.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index e0547b87b1..aa459afd3b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -123,7 +123,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { renderSelection(holder, showSelected) holder.roomAvatarPresenceImageView.render(showPresence, userPresence) showTypingViewIfNecessary(holder) - } private fun showTypingViewIfNecessary(holder: Holder) { From 962e9abc6bea1bfd0efa9105fd0db072b6f48a67 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:04:54 +0200 Subject: [PATCH 023/349] Fixes lint error --- .../app/features/home/room/list/RoomSummaryItemFactory.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index cc99c0eb6e..f9f61f730b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -54,7 +54,9 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor val changeMembershipState = roomChangeMembershipStates[roomSummary.roomId] ?: ChangeMembershipState.Unknown createInvitationItem(roomSummary, changeMembershipState, listener) } - else -> createRoomItem(roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked }) + else -> createRoomItem( + roomSummary, selectedRoomIds, displayMode, listener?.let { it::onRoomClicked }, listener?.let { it::onRoomLongClicked } + ) } } From 7e415e82b099dcb5111caffb05d1577f843fc3f8 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 28 Apr 2022 12:37:54 +0200 Subject: [PATCH 024/349] Fixes lint error --- .../vector/app/features/share/IncomingShareController.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index 7c82b7aea0..6926a54cc4 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -54,7 +54,13 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac } else { roomSummaries.forEach { roomSummary -> roomSummaryItemFactory - .createRoomItem(roomSummary, data.selectedRoomIds, RoomListDisplayMode.ROOMS /* TODO: Change */, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked }) + .createRoomItem( + roomSummary, + data.selectedRoomIds, + RoomListDisplayMode.ROOMS /* TODO: Change */, + callback?.let { it::onRoomClicked }, + callback?.let { it::onRoomLongClicked } + ) .addTo(this) } } From 042ec3628fc7caed9c15a936036f36a2ef64f79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 28 Apr 2022 19:02:48 +0200 Subject: [PATCH 025/349] Extract text size to style --- library/ui-styles/src/main/res/values/styles_timeline.xml | 7 +++++-- vector/src/main/res/layout/view_read_receipts.xml | 4 +--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/ui-styles/src/main/res/values/styles_timeline.xml b/library/ui-styles/src/main/res/values/styles_timeline.xml index c86eeb8efb..20c375c2d6 100644 --- a/library/ui-styles/src/main/res/values/styles_timeline.xml +++ b/library/ui-styles/src/main/res/values/styles_timeline.xml @@ -1,5 +1,5 @@ - + + - \ No newline at end of file + diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index e8101ec28d..11fdeb74d5 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -7,7 +7,7 @@ Date: Fri, 29 Apr 2022 12:37:19 +0200 Subject: [PATCH 026/349] Refactors RoomSummaryItem --- .../home/room/list/RoomSummaryItem.kt | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index aa459afd3b..4cea812775 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -105,14 +105,14 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { override fun bind(holder: Holder) { super.bind(holder) + + renderDisplayMode(holder) holder.rootView.onClick(itemClickListener) holder.rootView.setOnLongClickListener { it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) itemLongClickListener?.onLongClick(it) ?: false } holder.titleView.text = matrixItem.getBestName() - holder.lastEventTimeView.text = lastEventTime - holder.subtitleView.text = getTextForLastEventView() holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted)) holder.unreadIndentIndicator.isVisible = hasUnreadMessage holder.draftView.isVisible = hasDraft @@ -122,22 +122,24 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending renderSelection(holder, showSelected) holder.roomAvatarPresenceImageView.render(showPresence, userPresence) - showTypingViewIfNecessary(holder) } - private fun showTypingViewIfNecessary(holder: Holder) { - if (displayMode != RoomListDisplayMode.FILTERED) { - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible - } + private fun renderDisplayMode(holder: Holder) = when (displayMode) { + RoomListDisplayMode.ROOMS, + RoomListDisplayMode.PEOPLE, + RoomListDisplayMode.NOTIFICATIONS -> renderForDefaultDisplayMode(holder) + RoomListDisplayMode.FILTERED -> renderForFilteredDisplayMode(holder) } - private fun getTextForLastEventView(): CharSequence { - return if (displayMode == RoomListDisplayMode.FILTERED) { - subtitle - } else { - lastFormattedEvent.charSequence - } + private fun renderForDefaultDisplayMode(holder: Holder) { + holder.subtitleView.text = lastFormattedEvent.charSequence + holder.lastEventTimeView.text = lastEventTime + } + + private fun renderForFilteredDisplayMode(holder: Holder) { + holder.subtitleView.text = subtitle + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible } override fun unbind(holder: Holder) { From a355b625e9dd671af000970963eb4406f270faa0 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 29 Apr 2022 13:05:08 +0200 Subject: [PATCH 027/349] Adds displayMode to RoomSummaryListController --- .../vector/app/features/home/room/list/RoomListFragment.kt | 2 +- .../app/features/home/room/list/RoomSummaryListController.kt | 5 +++-- .../home/room/list/RoomSummaryPagedControllerFactory.kt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index cabaf11b75..65055346e6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -337,7 +337,7 @@ class RoomListFragment @Inject constructor( } } else -> { - pagedControllerFactory.createRoomSummaryListController() + pagedControllerFactory.createRoomSummaryListController(roomListParams.displayMode) .also { controller -> section.liveList?.observe(viewLifecycleOwner) { list -> controller.setData(list) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt index 683263dbbc..2eb8921fd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryListController.kt @@ -20,14 +20,15 @@ import im.vector.app.features.home.RoomListDisplayMode import org.matrix.android.sdk.api.session.room.model.RoomSummary class RoomSummaryListController( - private val roomSummaryItemFactory: RoomSummaryItemFactory + private val roomSummaryItemFactory: RoomSummaryItemFactory, + private val displayMode: RoomListDisplayMode ) : CollapsableTypedEpoxyController>() { var listener: RoomListListener? = null override fun buildModels(data: List?) { data?.forEach { - add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), RoomListDisplayMode.ROOMS /* TODO: change */, listener)) + add(roomSummaryItemFactory.create(it, emptyMap(), emptySet(), displayMode, listener)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt index 36f1b5ac90..f72698048d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedControllerFactory.kt @@ -27,8 +27,8 @@ class RoomSummaryPagedControllerFactory @Inject constructor( return RoomSummaryPagedController(roomSummaryItemFactory, displayMode) } - fun createRoomSummaryListController(): RoomSummaryListController { - return RoomSummaryListController(roomSummaryItemFactory) + fun createRoomSummaryListController(displayMode: RoomListDisplayMode): RoomSummaryListController { + return RoomSummaryListController(roomSummaryItemFactory, displayMode) } fun createSuggestedRoomListController(): SuggestedRoomListController { From f70a24d257f6e28c9c6c3cd5216b52293d1af410 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 29 Apr 2022 13:18:46 +0200 Subject: [PATCH 028/349] Changes IncomingShareController display mode to FILTERED --- .../im/vector/app/features/share/IncomingShareController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt index 6926a54cc4..bf5cedd5da 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt @@ -57,7 +57,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac .createRoomItem( roomSummary, data.selectedRoomIds, - RoomListDisplayMode.ROOMS /* TODO: Change */, + RoomListDisplayMode.FILTERED, callback?.let { it::onRoomClicked }, callback?.let { it::onRoomLongClicked } ) From 47493fcfa135ab6464fda974a45d9bd164ee5222 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:11:17 +0200 Subject: [PATCH 029/349] Replaces method for getting the space parents of rooms --- .../session/room/summary/RoomSummaryDataSource.kt | 13 +++++++++++++ .../session/room/summary/RoomSummaryUpdater.kt | 8 -------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 18a4f80547..a84f9aa7d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -37,6 +37,7 @@ import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomType +import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount @@ -197,6 +198,18 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) + }.map { roomSummary -> + val parents = roomSummary.flattenParentIds.mapNotNull { parentId -> + getRoomSummary(parentId)?.let { parentSummary -> + SpaceParentInfo( + parentId = parentSummary.flattenParentIds.firstOrNull(), + roomSummary = parentSummary, + canonical = true, + viaServers = emptyList() + ) + } + } + roomSummary.copy(spaceParents = parents) } val boundaries = MutableLiveData(ResultBoundaries()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 81979c6926..4a9f6c44c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm -import io.realm.RealmList import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse @@ -362,13 +361,6 @@ internal class RoomSummaryUpdater @Inject constructor( val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> - // TODO: Revisit - childSum.parents.add(SpaceParentSummaryEntity( - canonical = true, - parentRoomId = parent.roomId, - parentSummaryEntity = parent, - viaServers = RealmList() - )) if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { From 7881f7f9ea8ea05d145e1143c5fc7dea68539ad0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 2 May 2022 14:40:25 +0200 Subject: [PATCH 030/349] Add a final question to know if the issue submitter will provide a PR --- .github/ISSUE_TEMPLATE/bug.yml | 11 +++++++++++ .github/ISSUE_TEMPLATE/enhancement.yml | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index a7daaac14b..1ab5d835b2 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -73,3 +73,14 @@ body: - 'No' validations: required: true + - type: dropdown + id: pr + attributes: + label: Are you willing to provide a PR? + description: | + Providing a PR can drastically speed up the process of fixing this bug. Don't worry, it's still OK to answer 'No' :). + options: + - 'Yes' + - 'No' + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 71adce718e..2dd968951f 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -34,3 +34,14 @@ body: placeholder: Is there anything else you'd like to add? validations: required: false + - type: dropdown + id: pr + attributes: + label: Are you willing to provide a PR? + description: | + Don't worry, it's still OK to answer 'No' :). + options: + - 'Yes' + - 'No' + validations: + required: true From c9b32fec44515b26f4815f41a10dafc738e3c7d6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:42:56 +0200 Subject: [PATCH 031/349] Changes ordering of room subtitles used --- .../room/summary/RoomSummaryUpdater.kt | 21 +++++++++++++++---- .../home/room/list/RoomSummaryItemFactory.kt | 4 ++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 4a9f6c44c9..3af579d050 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -349,27 +349,39 @@ internal class RoomSummaryUpdater @Inject constructor( } val acyclicGraph = graph.withoutEdges(backEdges) +// Timber.v("## SPACES: acyclicGraph $acyclicGraph") val flattenSpaceParents = acyclicGraph.flattenDestination().map { it.key.name to it.value.map { it.name } }.toMap() +// Timber.v("## SPACES: flattenSpaceParents ${flattenSpaceParents.map { it.key.name to it.value.map { it.name } }.joinToString("\n") { +// it.first + ": [" + it.second.joinToString(",") + "]" +// }}") + +// Timber.v("## SPACES: lookup map ${lookupMap.map { it.key.name to it.value.map { it.name } }.toMap()}") lookupMap.entries .filter { it.key.roomType == RoomType.SPACE && it.key.membership == Membership.JOIN } .forEach { entry -> val parent = RoomSummaryEntity.where(realm, entry.key.roomId).findFirst() if (parent != null) { +// Timber.v("## SPACES: check hierarchy of ${parent.name} id ${parent.roomId}") +// Timber.v("## SPACES: flat known parents of ${parent.name} are ${flattenSpaceParents[parent.roomId]}") val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId) +// Timber.v("## SPACES: flatten known parents of children of ${parent.name} are ${flattenParentsIds}") entry.value.forEach { child -> RoomSummaryEntity.where(realm, child.roomId).findFirst()?.let { childSum -> + +// Timber.w("## SPACES: ${childSum.name} is ${childSum.roomId} fc: ${childSum.flattenParentIds}") +// var allParents = childSum.flattenParentIds ?: "" if (childSum.flattenParentIds == null) childSum.flattenParentIds = "" flattenParentsIds.forEach { if (childSum.flattenParentIds?.contains(it) != true) { - if (childSum.flattenParentIds?.isEmpty() == false) { - childSum.flattenParentIds += "|" - } - childSum.flattenParentIds += it + childSum.flattenParentIds += "|$it" } } +// childSum.flattenParentIds = "$allParents|" + +// Timber.v("## SPACES: flatten of ${childSum.name} is ${childSum.flattenParentIds}") } } } @@ -399,6 +411,7 @@ internal class RoomSummaryUpdater @Inject constructor( // we keep real m.child/m.parent relations and add the one for common memberships dmRoom.flattenParentIds += "|${flattenRelated.joinToString("|")}|" } +// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}") } // Maybe a good place to count the number of notifications for spaces? diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index f9f61f730b..05701b908f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -153,10 +153,10 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { - val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name val userId = roomSummary.directUserId + val spaceName = roomSummary.spaceParents?.firstOrNull()?.roomSummary?.name val canonicalAlias = roomSummary.canonicalAlias - return (spaceName ?: userId ?: canonicalAlias).orEmpty() + return (userId ?: spaceName ?: canonicalAlias).orEmpty() } } From b46794d4df2e863ef1799da1c1ae3e154ce49751 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 2 May 2022 14:44:23 +0200 Subject: [PATCH 032/349] Adds changelog file --- changelog.d/5860.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5860.feature diff --git a/changelog.d/5860.feature b/changelog.d/5860.feature new file mode 100644 index 0000000000..6c34fa0905 --- /dev/null +++ b/changelog.d/5860.feature @@ -0,0 +1 @@ +Adds space or user id as a subtitle under rooms in search From 87e740973cdf48f4507ad2197b4bd2238a931c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sat, 7 May 2022 20:06:03 +0200 Subject: [PATCH 033/349] Make read receipt avatar list compact --- .../app/core/ui/views/ReadReceiptsView.kt | 117 ++++++++---------- .../main/res/layout/view_read_receipts.xml | 30 ++--- vector/src/main/res/values/strings.xml | 2 +- 3 files changed, 60 insertions(+), 89 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt b/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt index 8477eddeea..2b7da49a71 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt @@ -28,8 +28,7 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.toMatrixItem -private const val MAX_RECEIPT_DISPLAYED = 5 -private const val MAX_RECEIPT_DESCRIBED = 3 +private const val MAX_RECEIPT_DISPLAYED = 3 class ReadReceiptsView @JvmOverloads constructor( context: Context, @@ -45,13 +44,7 @@ class ReadReceiptsView @JvmOverloads constructor( } private val receiptAvatars: List by lazy { - listOf( - views.receiptAvatar1, - views.receiptAvatar2, - views.receiptAvatar3, - views.receiptAvatar4, - views.receiptAvatar5 - ) + listOf(views.receiptAvatar1, views.receiptAvatar2, views.receiptAvatar3) } private fun setupView() { @@ -60,66 +53,58 @@ class ReadReceiptsView @JvmOverloads constructor( } fun render(readReceipts: List, avatarRenderer: AvatarRenderer) { - if (readReceipts.isNotEmpty()) { - isVisible = true - for (index in 0 until MAX_RECEIPT_DISPLAYED) { - val receiptData = readReceipts.getOrNull(index) - if (receiptData == null) { - receiptAvatars[index].visibility = View.INVISIBLE - } else { - receiptAvatars[index].visibility = View.VISIBLE - avatarRenderer.render(receiptData.toMatrixItem(), receiptAvatars[index]) - } - } + receiptAvatars.forEach { it.isVisible = false } - val displayNames = readReceipts - .mapNotNull { it.displayName } - .filter { it.isNotBlank() } - .take(MAX_RECEIPT_DESCRIBED) + readReceipts.take(MAX_RECEIPT_DISPLAYED).forEachIndexed { index, receiptData -> + receiptAvatars[index].isVisible = true + avatarRenderer.render(receiptData.toMatrixItem(), receiptAvatars[index]) + } - if (readReceipts.size > MAX_RECEIPT_DISPLAYED) { - views.receiptMore.visibility = View.VISIBLE - views.receiptMore.text = context.getString( - R.string.x_plus, readReceipts.size - MAX_RECEIPT_DISPLAYED - ) - } else { - views.receiptMore.visibility = View.GONE - } - contentDescription = when (readReceipts.size) { - 1 -> - if (displayNames.size == 1) { - context.getString(R.string.one_user_read, displayNames[0]) - } else { - context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) - } - 2 -> - if (displayNames.size == 2) { - context.getString(R.string.two_users_read, displayNames[0], displayNames[1]) - } else { - context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) - } - 3 -> - if (displayNames.size == 3) { - context.getString(R.string.three_users_read, displayNames[0], displayNames[1], displayNames[2]) - } else { - context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) - } - else -> - if (displayNames.size >= 2) { - val qty = readReceipts.size - 2 - context.resources.getQuantityString( - R.plurals.two_and_some_others_read, - qty, - displayNames[0], - displayNames[1], - qty - ) - } else { - context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) - } - } + val displayNames = readReceipts + .mapNotNull { it.displayName } + .filter { it.isNotBlank() } + .take(MAX_RECEIPT_DISPLAYED) + + if (readReceipts.size > MAX_RECEIPT_DISPLAYED) { + views.receiptMore.visibility = View.VISIBLE + views.receiptMore.text = context.getString( + R.string.x_plus, readReceipts.size - MAX_RECEIPT_DISPLAYED + ) } else { - isVisible = false + views.receiptMore.visibility = View.GONE + } + contentDescription = when (readReceipts.size) { + 1 -> + if (displayNames.size == 1) { + context.getString(R.string.one_user_read, displayNames[0]) + } else { + context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) + } + 2 -> + if (displayNames.size == 2) { + context.getString(R.string.two_users_read, displayNames[0], displayNames[1]) + } else { + context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) + } + 3 -> + if (displayNames.size == 3) { + context.getString(R.string.three_users_read, displayNames[0], displayNames[1], displayNames[2]) + } else { + context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) + } + else -> + if (displayNames.size >= 2) { + val qty = readReceipts.size - 2 + context.resources.getQuantityString( + R.plurals.two_and_some_others_read, + qty, + displayNames[0], + displayNames[1], + qty + ) + } else { + context.resources.getQuantityString(R.plurals.fallback_users_read, readReceipts.size) + } } } diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index 907f1ec0e3..dce46ec187 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:gravity="end" tools:parentTag="android.widget.LinearLayout"> - - - - @@ -52,9 +35,11 @@ android:id="@+id/receiptAvatar2" android:layout_width="@dimen/item_event_message_state_size" android:layout_height="@dimen/item_event_message_state_size" - android:layout_marginStart="2dp" + android:layout_marginEnd="-6dp" android:adjustViewBounds="true" + android:background="@drawable/pill_receipt" android:importantForAccessibility="no" + android:padding="1dp" android:scaleType="centerCrop" tools:src="@sample/user_round_avatars" /> @@ -62,9 +47,10 @@ android:id="@+id/receiptAvatar1" android:layout_width="@dimen/item_event_message_state_size" android:layout_height="@dimen/item_event_message_state_size" - android:layout_marginStart="2dp" android:adjustViewBounds="true" + android:background="@drawable/pill_receipt" android:importantForAccessibility="no" + android:padding="1dp" android:scaleType="centerCrop" tools:src="@sample/user_round_avatars" /> diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index d5bc322546..c16dd8b61a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1418,7 +1418,7 @@ collapse %1$s: %2$s - %d+ + +%d No valid Google Play Services APK found. Notifications may not work properly. From ed1179b15542eb339a2d7e176d5a7d9d7f62cb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Sat, 7 May 2022 20:44:58 +0200 Subject: [PATCH 034/349] Ignore lint warning about negative margin --- vector/src/main/res/layout/view_read_receipts.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index dce46ec187..0e8af014bd 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -29,6 +29,7 @@ android:importantForAccessibility="no" android:padding="1dp" android:scaleType="centerCrop" + tools:ignore="NegativeMargin" tools:src="@sample/user_round_avatars" /> Date: Fri, 13 May 2022 13:07:20 +0200 Subject: [PATCH 035/349] Adds vertical centering of title when no subtitle is present --- .../home/room/list/RoomSummaryItem.kt | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 4cea812775..0a97518cf1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -18,9 +18,10 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View -import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute @@ -134,12 +135,33 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForDefaultDisplayMode(holder: Holder) { holder.subtitleView.text = lastFormattedEvent.charSequence holder.lastEventTimeView.text = lastEventTime + holder.typingView.setTextOrHide(typingMessage) + holder.subtitleView.isInvisible = holder.typingView.isVisible } private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - holder.typingView.setTextOrHide(typingMessage) - holder.subtitleView.isInvisible = holder.typingView.isVisible + if (subtitle.isEmpty()) { + holder.centerTitleVertically() + } + } + + private fun Holder.centerTitleVertically() { + removeTitleTopMargin() + constrainTitleToParentBottom() + } + + private fun Holder.removeTitleTopMargin() { + val layoutParams = titleView.layoutParams as ConstraintLayout.LayoutParams + layoutParams.topMargin = 0 + titleView.layoutParams = layoutParams + } + + private fun Holder.constrainTitleToParentBottom() { + val constraintSet = ConstraintSet() + constraintSet.clone(rootView) + constraintSet.connect(titleView.id, ConstraintSet.BOTTOM, rootView.id, ConstraintSet.BOTTOM) + constraintSet.applyTo(rootView) } override fun unbind(holder: Holder) { @@ -175,6 +197,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarPublicDecorationImageView by bind(R.id.roomAvatarPublicDecorationImageView) val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) - val rootView by bind(R.id.itemRoomLayout) + val rootView by bind(R.id.itemRoomLayout) } } From 50839c206bf14e2783c8953275580f547a990ba2 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 13 May 2022 20:43:03 +0200 Subject: [PATCH 036/349] Adds flattenParents field to RoomSummary and corresponding mapping --- .../sdk/api/session/room/model/RoomSummary.kt | 1 + .../room/summary/RoomSummaryDataSource.kt | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt index 71c1d8303e..5a265c2b26 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt @@ -62,6 +62,7 @@ data class RoomSummary( val roomType: String? = null, val spaceParents: List? = null, val spaceChildren: List? = null, + val flattenParents: List = emptyList(), val flattenParentIds: List = emptyList(), val roomEncryptionAlgorithm: RoomEncryptionAlgorithm? = null ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index b165fb3001..752c828710 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -194,19 +194,7 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) - }.map { roomSummary -> - val parents = roomSummary.flattenParentIds.mapNotNull { parentId -> - getRoomSummary(parentId)?.let { parentSummary -> - SpaceParentInfo( - parentId = parentSummary.flattenParentIds.firstOrNull(), - roomSummary = parentSummary, - canonical = true, - viaServers = emptyList() - ) - } - } - roomSummary.copy(spaceParents = parents) - } + }.map { it.getWithParents()} val boundaries = MutableLiveData(ResultBoundaries()) @@ -245,6 +233,20 @@ internal class RoomSummaryDataSource @Inject constructor( } } + private fun RoomSummary.getWithParents(): RoomSummary { + val parents = flattenParentIds.mapNotNull { parentId -> + getRoomSummary(parentId)?.let { parentSummary -> + SpaceParentInfo( + parentId = parentSummary.flattenParentIds.firstOrNull(), + roomSummary = parentSummary, + canonical = true, + viaServers = emptyList() + ) + } + } + return copy(flattenParents = parents) + } + fun getCountLive(queryParams: RoomSummaryQueryParams): LiveData { val liveRooms = monarchy.findAllManagedWithChanges { roomSummariesQuery(it, queryParams) From 7c1d1c34647e6a860b68adc7913a63a8574159a4 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 16 May 2022 10:26:28 +0200 Subject: [PATCH 037/349] Adds centering of items with no subtitles --- .../home/room/list/RoomSummaryItem.kt | 25 ++++--------------- vector/src/main/res/layout/item_room.xml | 18 +++++++++++-- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index 0a97518cf1..abcfe0d5d8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -19,9 +19,9 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View import android.widget.ImageView +import android.widget.Space import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout -import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute @@ -141,27 +141,11 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - if (subtitle.isEmpty()) { - holder.centerTitleVertically() - } + holder.centerTitle(shouldCenter = subtitle.isEmpty()) } - private fun Holder.centerTitleVertically() { - removeTitleTopMargin() - constrainTitleToParentBottom() - } - - private fun Holder.removeTitleTopMargin() { - val layoutParams = titleView.layoutParams as ConstraintLayout.LayoutParams - layoutParams.topMargin = 0 - titleView.layoutParams = layoutParams - } - - private fun Holder.constrainTitleToParentBottom() { - val constraintSet = ConstraintSet() - constraintSet.clone(rootView) - constraintSet.connect(titleView.id, ConstraintSet.BOTTOM, rootView.id, ConstraintSet.BOTTOM) - constraintSet.applyTo(rootView) + private fun Holder.centerTitle(shouldCenter: Boolean) { + centerTitleSpace.isVisible = shouldCenter } override fun unbind(holder: Holder) { @@ -198,5 +182,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) val rootView by bind(R.id.itemRoomLayout) + val centerTitleSpace by bind(R.id.centerTitleSpace) } } diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index ab0af18acb..ac028ccb08 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -112,13 +112,27 @@ app:layout_constraintTop_toBottomOf="@id/roomAvatarContainer" tools:layout_marginStart="20dp" /> + + + + Date: Mon, 16 May 2022 10:31:16 +0200 Subject: [PATCH 038/349] Fixes lint error --- .../sdk/internal/session/room/summary/RoomSummaryDataSource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 752c828710..f3ad4cbdd3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -194,7 +194,7 @@ internal class RoomSummaryDataSource @Inject constructor( } val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) - }.map { it.getWithParents()} + }.map { it.getWithParents() } val boundaries = MutableLiveData(ResultBoundaries()) From 2e08c07dad693c1ff78c4ab1da46e1ed9cf45bb8 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Mon, 16 May 2022 13:05:38 +0300 Subject: [PATCH 039/349] Enhance decryption to prevent DUPLICATED_MESSAGE_INDEX when decrypting the same eventId Improve code format --- .../crypto/replay_attack/ReplayAttackTest.kt | 160 ++++++++++++++++++ .../sdk/internal/crypto/MXOlmDevice.kt | 100 ++++++----- .../algorithms/megolm/MXMegolmDecryption.kt | 1 + 3 files changed, 218 insertions(+), 43 deletions(-) create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt new file mode 100644 index 0000000000..5c9892e264 --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.replay_attack + +import android.util.Log +import androidx.test.filters.LargeTest +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.TestConstants + +@RunWith(JUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +@LargeTest +class ReplayAttackTest : InstrumentedTest { + + @Test + fun replayAttackTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + Log.v("##REPLAY ATTACK", "Alice and Bob are in roomId: $e2eRoomID") + + + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello", 20) + +// val aliceMessageId: String? = sendMessageInRoom(aliceRoomPOV, "Hello Bob, I am Alice!", testHelper) + Assert.assertTrue("Message should be sent", sentEvents.size == 20) + Log.v("##REPLAY ATTACK", "Alice sent message to roomId: $e2eRoomID") + + // Bob should be able to decrypt the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = bobSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) +// (timelineEvent != null && +// timelineEvent.isEncrypted() && +// timelineEvent.root.getClearType() == EventType.MESSAGE).also { +// if (it) { +// Log.v("#E2E TEST", "Bob can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") +// } +// } +// } +// } +// +// // Create a new user +// val arisSession = testHelper.createAccount("aris", SessionTestParams(true)) +// Log.v("#E2E TEST", "Aris user created") +// +// // Alice invites new user to the room +// testHelper.runBlockingTest { +// Log.v("#E2E TEST", "Alice invites ${arisSession.myUserId}") +// aliceRoomPOV.membershipService().invite(arisSession.myUserId) +// } +// +// waitForAndAcceptInviteInRoom(arisSession, e2eRoomID, testHelper) +// +// ensureMembersHaveJoined(aliceSession, arrayListOf(arisSession), e2eRoomID, testHelper) +// Log.v("#E2E TEST", "Aris has joined roomId: $e2eRoomID") +// +// when (roomHistoryVisibility) { +// RoomHistoryVisibility.WORLD_READABLE, +// RoomHistoryVisibility.SHARED, +// null +// -> { +// // Aris should be able to decrypt the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) +// (timelineEvent != null && +// timelineEvent.isEncrypted() && +// timelineEvent.root.getClearType() == EventType.MESSAGE +// ).also { +// if (it) { +// Log.v("#E2E TEST", "Aris can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") +// } +// } +// } +// } +// } +// RoomHistoryVisibility.INVITED, +// RoomHistoryVisibility.JOINED -> { +// // Aris should not even be able to get the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID) +// ?.timelineService() +// ?.getTimelineEvent(aliceMessageId!!) +// timelineEvent == null +// } +// } +// } +// } + +// testHelper.signOutAndClose(arisSession) + cryptoTestData.cleanUp(testHelper) + } + + private fun sendMessageInRoom(aliceRoomPOV: Room, text: String, testHelper: CommonTestHelper): String? { + aliceRoomPOV.sendService().sendTextMessage(text) + var sentEventId: String? = null + testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch -> + val timeline = aliceRoomPOV.timelineService().createTimeline(null, TimelineSettings(60)) + timeline.start() + testHelper.retryPeriodicallyWithLatch(latch) { + val decryptedMsg = timeline.getSnapshot() + .filter { it.root.getClearType() == EventType.MESSAGE } + .also { list -> + val message = list.joinToString(",", "[", "]") { "${it.root.type}|${it.root.sendState}" } + Log.v("#E2E TEST", "Timeline snapshot is $message") + } + .filter { it.root.sendState == SendState.SYNCED } + .firstOrNull { it.root.getClearContent().toModel()?.body?.startsWith(text) == true } + sentEventId = decryptedMsg?.eventId + decryptedMsg != null + } + + timeline.dispose() + } + return sentEventId + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 68a1519670..16e6bb173d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -99,6 +99,8 @@ internal class MXOlmDevice @Inject constructor( // The second level keys are strings of form "||" private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() + private val replayAttackMap: MutableMap = HashMap() + init { // Retrieve the account from the store try { @@ -763,59 +765,71 @@ internal class MXOlmDevice @Inject constructor( suspend fun decryptGroupMessage(body: String, roomId: String, timeline: String?, + eventId: String, sessionId: String, senderKey: String): OlmDecryptionResult { val sessionHolder = getInboundGroupSession(sessionId, senderKey, roomId) val wrapper = sessionHolder.wrapper val inboundGroupSession = wrapper.olmInboundGroupSession ?: throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, "Session is null") - // Check that the room id matches the original one for the session. This stops - // the HS pretending a message was targeting a different room. - if (roomId == wrapper.roomId) { - val decryptResult = try { - sessionHolder.mutex.withLock { - inboundGroupSession.decryptMessage(body) - } - } catch (e: OlmException) { - Timber.tag(loggerTag.value).e(e, "## decryptGroupMessage () : decryptMessage failed") - throw MXCryptoError.OlmError(e) - } - - if (timeline?.isNotBlank() == true) { - val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } - - val messageIndexKey = senderKey + "|" + sessionId + "|" + decryptResult.mIndex - - if (timelineSet.contains(messageIndexKey)) { - val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) - Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") - throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) - } - - timelineSet.add(messageIndexKey) - } - - inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) - val payload = try { - val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) - val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) - adapter.fromJson(payloadString) - } catch (e: Exception) { - Timber.tag(loggerTag.value).e("## decryptGroupMessage() : fails to parse the payload") - throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON) - } - - return OlmDecryptionResult( - payload, - wrapper.keysClaimed, - senderKey, - wrapper.forwardingCurve25519KeyChain - ) - } else { + if (roomId != wrapper.roomId) { + // Check that the room id matches the original one for the session. This stops + // the HS pretending a message was targeting a different room. val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, wrapper.roomId) Timber.tag(loggerTag.value).e("## decryptGroupMessage() : $reason") throw MXCryptoError.Base(MXCryptoError.ErrorType.INBOUND_SESSION_MISMATCH_ROOM_ID, reason) } + val decryptResult = try { + sessionHolder.mutex.withLock { + inboundGroupSession.decryptMessage(body) + } + } catch (e: OlmException) { + Timber.tag(loggerTag.value).e(e, "## decryptGroupMessage () : decryptMessage failed") + throw MXCryptoError.OlmError(e) + } + + val messageIndexKey = senderKey + "|" + sessionId + "|" + roomId + "|" + decryptResult.mIndex + Timber.tag(loggerTag.value).d("##########################################################") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() timeline: $timeline") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() senderKey: $senderKey") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() sessionId: $sessionId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() roomId: $roomId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() eventId: $eventId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") + + if (timeline?.isNotBlank() == true) { + val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } + if (timelineSet.contains(messageIndexKey) && messageIndexKey.alreadyUsed(eventId)) { + val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) + Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") + throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) + } + timelineSet.add(messageIndexKey) + } + replayAttackMap[messageIndexKey] = eventId + inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) + val payload = try { + val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) + val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) + adapter.fromJson(payloadString) + } catch (e: Exception) { + Timber.tag(loggerTag.value).e("## decryptGroupMessage() : fails to parse the payload") + throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON) + } + + return OlmDecryptionResult( + payload, + wrapper.keysClaimed, + senderKey, + wrapper.forwardingCurve25519KeyChain + ) + } + + /** + * Determines whether or not the messageKey has already been used to decrypt another eventId + */ + private fun String.alreadyUsed(eventId: String): Boolean { + return replayAttackMap[this] != null && replayAttackMap[this] != eventId } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index d65b05f655..aff8013784 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -78,6 +78,7 @@ internal class MXMegolmDecryption( encryptedEventContent.ciphertext, event.roomId, timeline, + eventId = event.eventId.orEmpty(), encryptedEventContent.sessionId, encryptedEventContent.senderKey ) From a893f5acdb74c2553ffc7cbbd8991f27f4aa3fed Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 12:00:53 +0100 Subject: [PATCH 040/349] applying the manual reordering of the sign up stages only when matrix.org is selected - lifts the logic up to the view model --- changelog.d/5783.wip | 1 + .../app/features/onboarding/OnboardingViewModel.kt | 13 ++++++++++++- .../features/onboarding/ftueauth/FtueAuthVariant.kt | 8 +------- 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 changelog.d/5783.wip diff --git a/changelog.d/5783.wip b/changelog.d/5783.wip new file mode 100644 index 0000000000..6f44813d81 --- /dev/null +++ b/changelog.d/5783.wip @@ -0,0 +1 @@ +FTUE - Overrides sign up flow ordering for matrix.org only diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 25ae0327a8..a7468cf95b 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,6 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult +import im.vector.app.features.onboarding.ftueauth.FtueMissingRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -289,9 +290,19 @@ class OnboardingViewModel @AssistedInject constructor( } private fun emitFlowResultViewEvent(flowResult: FlowResult) { - _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted)) + withState { state -> + val orderedResult = when { + state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.overrideOrder() + else -> flowResult + } + _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(orderedResult, isRegistrationStarted)) + } } + private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl + + private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(FtueMissingRegistrationStagesComparator())) + private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password handleRegisterAction( diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 63b3bc0f71..8513845b8e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -54,7 +54,6 @@ import im.vector.app.features.onboarding.OnboardingViewState import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthLegacyStyleTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsLegacyStyleFragmentArgument -import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.auth.toLocalizedLoginTerms import org.matrix.android.sdk.api.extensions.tryOrNull @@ -240,17 +239,12 @@ class FtueAuthVariant( private fun onRegistrationFlow(viewEvents: OnboardingViewEvents.RegistrationFlowResult) { when { registrationShouldFallback(viewEvents) -> displayFallbackWebDialog() - viewEvents.isRegistrationStarted -> handleRegistrationNavigation(viewEvents.flowResult.orderedStages()) + viewEvents.isRegistrationStarted -> handleRegistrationNavigation(viewEvents.flowResult.missingStages) vectorFeatures.isOnboardingCombinedRegisterEnabled() -> openStartCombinedRegister() else -> openAuthLoginFragmentWithTag(FRAGMENT_REGISTRATION_STAGE_TAG) } } - private fun FlowResult.orderedStages() = when { - vectorFeatures.isOnboardingCombinedRegisterEnabled() -> missingStages.sortedWith(FtueMissingRegistrationStagesComparator()) - else -> missingStages - } - private fun openStartCombinedRegister() { addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java) } From 6c3150edb7e671e522369ed63f16ff20a13dd5eb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:16:37 +0100 Subject: [PATCH 041/349] using compareTo instead of direct subtraction --- .../ftueauth/FtueMissingRegistrationStagesComparator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt index 6a6326625e..4d9fe10852 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.api.auth.registration.Stage class FtueMissingRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { - return (a?.toPriority() ?: 0) - (b?.toPriority() ?: 0) + return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) } private fun Stage.toPriority() = when (this) { From 51ffe26a919a8b0e999496d7eb5cb16f8095d413 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:17:15 +0100 Subject: [PATCH 042/349] renaming comparator to give more context to its usage --- .../im/vector/app/features/onboarding/OnboardingViewModel.kt | 4 ++-- ...tor.kt => MatrixOrgMissingRegistrationStagesComparator.kt} | 2 +- ...kt => MatrixOrgMissingRegistrationStagesComparatorTest.kt} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename vector/src/main/java/im/vector/app/features/onboarding/ftueauth/{FtueMissingRegistrationStagesComparator.kt => MatrixOrgMissingRegistrationStagesComparator.kt} (93%) rename vector/src/test/java/im/vector/app/features/onboarding/ftueauth/{FtueMissingRegistrationStagesComparatorTest.kt => MatrixOrgMissingRegistrationStagesComparatorTest.kt} (91%) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index a7468cf95b..94bb36dbbc 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,7 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult -import im.vector.app.features.onboarding.ftueauth.FtueMissingRegistrationStagesComparator +import im.vector.app.features.onboarding.ftueauth.MatrixOrgMissingRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -301,7 +301,7 @@ class OnboardingViewModel @AssistedInject constructor( private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl - private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(FtueMissingRegistrationStagesComparator())) + private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator())) private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt similarity index 93% rename from vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt rename to vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt index 4d9fe10852..894a474a9e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt @@ -18,7 +18,7 @@ package im.vector.app.features.onboarding.ftueauth import org.matrix.android.sdk.api.auth.registration.Stage -class FtueMissingRegistrationStagesComparator : Comparator { +class MatrixOrgMissingRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt similarity index 91% rename from vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt rename to vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt index 010cf5de60..1fe8ad6000 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt @@ -25,7 +25,7 @@ import im.vector.app.test.fixtures.anOtherStage import org.amshove.kluent.shouldBeEqualTo import org.junit.Test -class FtueMissingRegistrationStagesComparatorTest { +class MatrixOrgMissingRegistrationStagesComparatorTest { @Test fun `when ordering stages, then prioritizes email`() { @@ -38,7 +38,7 @@ class FtueMissingRegistrationStagesComparatorTest { aTermsStage() ) - val result = input.sortedWith(FtueMissingRegistrationStagesComparator()) + val result = input.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) result shouldBeEqualTo listOf( anEmailStage(), From 444980395eb33c84749d93aede4950f014dfe2ce Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:26:12 +0100 Subject: [PATCH 043/349] inlining single use extension --- .../vector/app/features/onboarding/OnboardingViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 94bb36dbbc..8424a5e915 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -292,7 +292,9 @@ class OnboardingViewModel @AssistedInject constructor( private fun emitFlowResultViewEvent(flowResult: FlowResult) { withState { state -> val orderedResult = when { - state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.overrideOrder() + state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.copy( + missingStages = flowResult.missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + ) else -> flowResult } _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(orderedResult, isRegistrationStarted)) @@ -301,8 +303,6 @@ class OnboardingViewModel @AssistedInject constructor( private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl - private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator())) - private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password handleRegisterAction( From 271bc91303f4f2cff85204b956581e6d30f4fae3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 23:08:43 +0000 Subject: [PATCH 044/349] Bump vanniktechEmoji from 0.9.0 to 0.12.0 Bumps `vanniktechEmoji` from 0.9.0 to 0.12.0. Updates `emoji-material` from 0.9.0 to 0.12.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.12.0) Updates `emoji-google` from 0.9.0 to 0.12.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.12.0) --- updated-dependencies: - dependency-name: com.vanniktech:emoji-material dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.vanniktech:emoji-google dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 10f9539e5a..b868f74cd1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -23,7 +23,7 @@ def mavericks = "2.6.1" def glide = "4.13.2" def bigImageViewer = "1.8.1" def jjwt = "0.11.5" -def vanniktechEmoji = "0.9.0" +def vanniktechEmoji = "0.12.0" // Testing def mockk = "1.12.4" From e706c5a3c8c264feb3d0b19e5efe3dbd56d9dd35 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 11:09:14 +0200 Subject: [PATCH 045/349] Adds up navigation from spaces --- .../vector/app/features/home/HomeActivity.kt | 75 ++++++++++--------- .../features/home/HomeActivitySharedAction.kt | 3 +- .../app/features/home/HomeDetailFragment.kt | 70 ++++++++--------- .../src/main/res/drawable/ic_arrow_back.xml | 5 ++ .../main/res/layout/fragment_home_detail.xml | 17 ++++- vector/src/main/res/values/strings.xml | 1 + 6 files changed, 98 insertions(+), 73 deletions(-) create mode 100644 vector/src/main/res/drawable/ic_arrow_back.xml diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index cc202868cc..b4943ce1b4 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -199,43 +199,13 @@ class HomeActivity : when (sharedAction) { is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) - is HomeActivitySharedAction.OpenGroup -> { - views.drawerLayout.closeDrawer(GravityCompat.START) - - // Temporary - // When switching from space to group or group to space, we need to reload the fragment - // To be removed when dropping legacy groups - if (sharedAction.clearFragment) { - replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) - } else { - // nop - } - // we might want to delay that to avoid having the drawer animation lagging - // would be probably better to let the drawer do that? in the on closed callback? - } - is HomeActivitySharedAction.OpenSpacePreview -> { - startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId)) - } - is HomeActivitySharedAction.AddSpace -> { - createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this)) - } - is HomeActivitySharedAction.ShowSpaceSettings -> { - // open bottom sheet - SpaceSettingsMenuBottomSheet - .newInstance(sharedAction.spaceId, object : SpaceSettingsMenuBottomSheet.InteractionListener { - override fun onShareSpaceSelected(spaceId: String) { - ShareSpaceBottomSheet.show(supportFragmentManager, spaceId) - } - }) - .show(supportFragmentManager, "SPACE_SETTINGS") - } - is HomeActivitySharedAction.OpenSpaceInvite -> { - SpaceInviteBottomSheet.newInstance(sharedAction.spaceId) - .show(supportFragmentManager, "SPACE_INVITE") - } - HomeActivitySharedAction.SendSpaceFeedBack -> { - bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) - } + is HomeActivitySharedAction.OpenGroup -> openGroup(sharedAction.shouldClearFragment) + is HomeActivitySharedAction.OpenSpacePreview -> startActivity(SpacePreviewActivity.newIntent(this, sharedAction.spaceId)) + is HomeActivitySharedAction.AddSpace -> createSpaceResultLauncher.launch(SpaceCreationActivity.newIntent(this)) + is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId) + is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId) + HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) + HomeActivitySharedAction.CloseGroup -> closeGroup() } } .launchIn(lifecycleScope) @@ -272,6 +242,37 @@ class HomeActivity : homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted) } + private fun openGroup(shouldClearFragment: Boolean) { + views.drawerLayout.closeDrawer(GravityCompat.START) + + // When switching from space to group or group to space, we need to reload the fragment + if (shouldClearFragment) { + replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) + } else { + // do nothing + } + } + + private fun showSpaceSettings(spaceId: String) { + // open bottom sheet + SpaceSettingsMenuBottomSheet + .newInstance(spaceId, object : SpaceSettingsMenuBottomSheet.InteractionListener { + override fun onShareSpaceSelected(spaceId: String) { + ShareSpaceBottomSheet.show(supportFragmentManager, spaceId) + } + }) + .show(supportFragmentManager, "SPACE_SETTINGS") + } + + private fun openSpaceInvite(spaceId: String) { + SpaceInviteBottomSheet.newInstance(spaceId) + .show(supportFragmentManager, "SPACE_INVITE") + } + + private fun closeGroup() { + views.drawerLayout.openDrawer(GravityCompat.START) + } + private fun handleShowAnalyticsOptIn() { navigator.openAnalyticsOptIn(this) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt index 6047a1e55e..cebde7fe0a 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivitySharedAction.kt @@ -24,7 +24,8 @@ import im.vector.app.core.platform.VectorSharedAction sealed class HomeActivitySharedAction : VectorSharedAction { object OpenDrawer : HomeActivitySharedAction() object CloseDrawer : HomeActivitySharedAction() - data class OpenGroup(val clearFragment: Boolean) : HomeActivitySharedAction() + data class OpenGroup(val shouldClearFragment: Boolean) : HomeActivitySharedAction() + object CloseGroup : HomeActivitySharedAction() object AddSpace : HomeActivitySharedAction() data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction() data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 2753ba817d..9ab1ad60e7 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -60,6 +60,11 @@ import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject +/* + * TODO: + * 1) Change the hamburger menu to a back button when in a space + * 2) Make the back navigation button follow the same behaviour + */ class HomeDetailFragment @Inject constructor( private val avatarRenderer: AvatarRenderer, private val colorProvider: ColorProvider, @@ -130,12 +135,8 @@ class HomeDetailFragment @Inject constructor( viewModel.onEach(HomeDetailViewState::roomGroupingMethod) { roomGroupingMethod -> when (roomGroupingMethod) { - is RoomGroupingMethod.ByLegacyGroup -> { - onGroupChange(roomGroupingMethod.groupSummary) - } - is RoomGroupingMethod.BySpace -> { - onSpaceChange(roomGroupingMethod.spaceSummary) - } + is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary) + is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary) } } @@ -147,6 +148,10 @@ class HomeDetailFragment @Inject constructor( updateTabVisibilitySafely(R.id.bottom_action_dial_pad, showDialPadTab) } + views.groupToolbarNavigateUp.setOnClickListener { + navigateUpOneParentSpace() + } + viewModel.observeViewEvents { viewEvent -> when (viewEvent) { HomeDetailViewEvents.CallStarted -> handleCallStarted() @@ -157,7 +162,6 @@ class HomeDetailFragment @Inject constructor( unknownDeviceDetectorSharedViewModel.onEach { state -> state.unknownSessions.invoke()?.let { unknownDevices -> -// Timber.v("## Detector Triggerred in fragment - ${unknownDevices.firstOrNull()}") if (unknownDevices.firstOrNull()?.currentSessionTrust == true) { val uid = "review_login" alertManager.cancelAlert(uid) @@ -190,6 +194,15 @@ class HomeDetailFragment @Inject constructor( } } + private fun navigateUpOneParentSpace() = with(appStateHandler) { + val parentId = when (val roomGroupingMethod = getCurrentRoomGroupingMethod()) { + is RoomGroupingMethod.BySpace -> roomGroupingMethod.spaceSummary?.flattenParentIds?.firstOrNull { it.isNotBlank() } + else -> null + } + setCurrentSpace(parentId) + sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup) + } + private fun handleCallStarted() { dismissLoadingDialog() val fragmentTag = HomeTab.DialPad.toFragmentTag() @@ -203,20 +216,16 @@ class HomeDetailFragment @Inject constructor( override fun onResume() { super.onResume() - // update notification tab if needed updateTabVisibilitySafely(R.id.bottom_action_notification, vectorPreferences.labAddNotificationTab()) callManager.checkForProtocolsSupportIfNeeded() + refreshSpaceState() + } - // Current space/group is not live so at least refresh toolbar on resume - appStateHandler.getCurrentRoomGroupingMethod()?.let { roomGroupingMethod -> - when (roomGroupingMethod) { - is RoomGroupingMethod.ByLegacyGroup -> { - onGroupChange(roomGroupingMethod.groupSummary) - } - is RoomGroupingMethod.BySpace -> { - onSpaceChange(roomGroupingMethod.spaceSummary) - } - } + private fun refreshSpaceState() { + when (val roomGroupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { + is RoomGroupingMethod.ByLegacyGroup -> onGroupChange(roomGroupingMethod.groupSummary) + is RoomGroupingMethod.BySpace -> onSpaceChange(roomGroupingMethod.spaceSummary) + else -> Unit } } @@ -260,12 +269,12 @@ class HomeDetailFragment @Inject constructor( viewBinder = VerificationVectorAlert.ViewBinder(user, avatarRenderer) colorInt = colorProvider.getColorFromAttribute(R.attr.colorPrimary) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { activity -> // mark as ignored to avoid showing it again unknownDeviceDetectorSharedViewModel.handle( UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId }) ) - it.navigator.openSettings(it, EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS) + activity.navigator.openSettings(activity, EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS) } } dismissedAction = Runnable { @@ -289,9 +298,13 @@ class HomeDetailFragment @Inject constructor( private fun onSpaceChange(spaceSummary: RoomSummary?) { if (spaceSummary == null) { views.groupToolbarSpaceTitleView.isVisible = false + views.groupToolbarAvatarImageView.isVisible = true + views.groupToolbarNavigateUp.isVisible = false } else { views.groupToolbarSpaceTitleView.isVisible = true views.groupToolbarSpaceTitleView.text = spaceSummary.displayName + views.groupToolbarAvatarImageView.isVisible = false + views.groupToolbarNavigateUp.isVisible = true } } @@ -324,11 +337,11 @@ class HomeDetailFragment @Inject constructor( withState(viewModel) { when (it.roomGroupingMethod) { is RoomGroupingMethod.ByLegacyGroup -> { - // nothing do far + // do nothing } is RoomGroupingMethod.BySpace -> { - it.roomGroupingMethod.spaceSummary?.let { - sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(it.roomId)) + it.roomGroupingMethod.spaceSummary?.let { spaceSummary -> + sharedActionViewModel.post(HomeActivitySharedAction.ShowSpaceSettings(spaceSummary.roomId)) } } } @@ -348,17 +361,6 @@ class HomeDetailFragment @Inject constructor( viewModel.handle(HomeDetailAction.SwitchTab(tab)) true } - -// val menuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView - -// bottomNavigationView.getOrCreateBadge() -// menuView.forEachIndexed { index, view -> -// val itemView = view as BottomNavigationItemView -// val badgeLayout = LayoutInflater.from(requireContext()).inflate(R.layout.vector_home_badge_unread_layout, menuView, false) -// val unreadCounterBadgeView: UnreadCounterBadgeView = badgeLayout.findViewById(R.id.actionUnreadCounterBadgeView) -// itemView.addView(badgeLayout) -// unreadCounterBadgeViews.add(index, unreadCounterBadgeView) -// } } private fun updateUIForTab(tab: HomeTab) { diff --git a/vector/src/main/res/drawable/ic_arrow_back.xml b/vector/src/main/res/drawable/ic_arrow_back.xml new file mode 100644 index 0000000000..8452791cfd --- /dev/null +++ b/vector/src/main/res/drawable/ic_arrow_back.xml @@ -0,0 +1,5 @@ + + + diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index a53f001125..c734f55a4e 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -38,6 +38,7 @@ android:layout_height="40dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" + android:visibility="gone" android:contentDescription="@string/a11y_open_drawer" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -74,6 +75,20 @@ + + - \ No newline at end of file + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 3e6bdad70b..c0421c7d6c 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1777,6 +1777,7 @@ Send attachment Open the navigation drawer + Navigate up one space Open the create room menu Close the create room menu… Create a new direct conversation From bc500a567a96a1fe6611b18c29c344ec52f03a03 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 11:28:37 +0200 Subject: [PATCH 046/349] Adds back button implementation of navigating up spaces --- .../app/features/home/HomeDetailFragment.kt | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 9ab1ad60e7..f7266db214 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -33,6 +33,7 @@ import im.vector.app.R import im.vector.app.RoomGroupingMethod import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.toMvRxBundle +import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider @@ -60,11 +61,6 @@ import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject -/* - * TODO: - * 1) Change the hamburger menu to a back button when in a space - * 2) Make the back navigation button follow the same behaviour - */ class HomeDetailFragment @Inject constructor( private val avatarRenderer: AvatarRenderer, private val colorProvider: ColorProvider, @@ -74,7 +70,8 @@ class HomeDetailFragment @Inject constructor( private val appStateHandler: AppStateHandler ) : VectorBaseFragment(), KeysBackupBanner.Delegate, - CurrentCallsView.Callback { + CurrentCallsView.Callback, + OnBackPressed { private val viewModel: HomeDetailViewModel by fragmentViewModel() private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel() @@ -149,7 +146,7 @@ class HomeDetailFragment @Inject constructor( } views.groupToolbarNavigateUp.setOnClickListener { - navigateUpOneParentSpace() + navigateUpOneSpace() } viewModel.observeViewEvents { viewEvent -> @@ -194,15 +191,14 @@ class HomeDetailFragment @Inject constructor( } } - private fun navigateUpOneParentSpace() = with(appStateHandler) { - val parentId = when (val roomGroupingMethod = getCurrentRoomGroupingMethod()) { - is RoomGroupingMethod.BySpace -> roomGroupingMethod.spaceSummary?.flattenParentIds?.firstOrNull { it.isNotBlank() } - else -> null - } - setCurrentSpace(parentId) + private fun navigateUpOneSpace() { + val parentId = getCurrentSpace()?.flattenParentIds?.lastOrNull() + appStateHandler.setCurrentSpace(parentId) sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup) } + private fun getCurrentSpace() = (appStateHandler.getCurrentRoomGroupingMethod() as? RoomGroupingMethod.BySpace)?.spaceSummary + private fun handleCallStarted() { dismissLoadingDialog() val fragmentTag = HomeTab.DialPad.toFragmentTag() @@ -438,7 +434,6 @@ class HomeDetailFragment @Inject constructor( } override fun invalidate() = withState(viewModel) { -// Timber.v(it.toString()) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup) @@ -498,4 +493,11 @@ class HomeDetailFragment @Inject constructor( } return this } + + override fun onBackPressed(toolbarButton: Boolean) = if (getCurrentSpace() != null) { + navigateUpOneSpace() + true + } else { + false + } } From 1ec99ee89e85ef16823991fd6e00669a84a6131c Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 17 May 2022 10:31:32 +0100 Subject: [PATCH 047/349] renaming comparator to only specify the matrix.org domain --- .../im/vector/app/features/onboarding/OnboardingViewModel.kt | 4 ++-- ...Comparator.kt => MatrixOrgRegistrationStagesComparator.kt} | 2 +- ...orTest.kt => MatrixOrgRegistrationStagesComparatorTest.kt} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename vector/src/main/java/im/vector/app/features/onboarding/ftueauth/{MatrixOrgMissingRegistrationStagesComparator.kt => MatrixOrgRegistrationStagesComparator.kt} (93%) rename vector/src/test/java/im/vector/app/features/onboarding/ftueauth/{MatrixOrgMissingRegistrationStagesComparatorTest.kt => MatrixOrgRegistrationStagesComparatorTest.kt} (91%) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 8424a5e915..9fd013ee79 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,7 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult -import im.vector.app.features.onboarding.ftueauth.MatrixOrgMissingRegistrationStagesComparator +import im.vector.app.features.onboarding.ftueauth.MatrixOrgRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -293,7 +293,7 @@ class OnboardingViewModel @AssistedInject constructor( withState { state -> val orderedResult = when { state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.copy( - missingStages = flowResult.missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + missingStages = flowResult.missingStages.sortedWith(MatrixOrgRegistrationStagesComparator()) ) else -> flowResult } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt similarity index 93% rename from vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt rename to vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt index 894a474a9e..fcc70803a0 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt @@ -18,7 +18,7 @@ package im.vector.app.features.onboarding.ftueauth import org.matrix.android.sdk.api.auth.registration.Stage -class MatrixOrgMissingRegistrationStagesComparator : Comparator { +class MatrixOrgRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt similarity index 91% rename from vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt rename to vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt index 1fe8ad6000..08be0ee058 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt @@ -25,7 +25,7 @@ import im.vector.app.test.fixtures.anOtherStage import org.amshove.kluent.shouldBeEqualTo import org.junit.Test -class MatrixOrgMissingRegistrationStagesComparatorTest { +class MatrixOrgRegistrationStagesComparatorTest { @Test fun `when ordering stages, then prioritizes email`() { @@ -38,7 +38,7 @@ class MatrixOrgMissingRegistrationStagesComparatorTest { aTermsStage() ) - val result = input.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + val result = input.sortedWith(MatrixOrgRegistrationStagesComparator()) result shouldBeEqualTo listOf( anEmailStage(), From 5f2cb671e2d27361b0e1561035fe1265d4061e6b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 17 May 2022 10:35:14 +0100 Subject: [PATCH 048/349] making comparator override non null as kotlin guards against this --- .../ftueauth/MatrixOrgRegistrationStagesComparator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt index fcc70803a0..527c20987a 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt @@ -20,8 +20,8 @@ import org.matrix.android.sdk.api.auth.registration.Stage class MatrixOrgRegistrationStagesComparator : Comparator { - override fun compare(a: Stage?, b: Stage?): Int { - return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) + override fun compare(a: Stage, b: Stage): Int { + return a.toPriority().compareTo(b.toPriority()) } private fun Stage.toPriority() = when (this) { From 520c3e474cf1a39dfb4cad36edfd87620bae6f47 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 12:02:29 +0200 Subject: [PATCH 049/349] Adds changelog file --- changelog.d/6073.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6073.feature diff --git a/changelog.d/6073.feature b/changelog.d/6073.feature new file mode 100644 index 0000000000..295f45f3ce --- /dev/null +++ b/changelog.d/6073.feature @@ -0,0 +1 @@ +Adds up navigation in spaces From 4adaa20f728d72bb0847c9107d44c7f09458060d Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 12:16:45 +0200 Subject: [PATCH 050/349] Fixes default visibilities in fragment_home_detail --- vector/src/main/res/layout/fragment_home_detail.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index c734f55a4e..301abef4b8 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -38,7 +38,6 @@ android:layout_height="40dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - android:visibility="gone" android:contentDescription="@string/a11y_open_drawer" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -82,7 +81,7 @@ android:src="@drawable/ic_arrow_back" android:layout_marginEnd="8dp" android:contentDescription="@string/a11y_navigate_up_space" - android:visibility="visible" + android:visibility="gone" app:tint="?vctr_content_secondary" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" From a0a7d3e7f6963aa27ab6a91c580ce580b0721226 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Tue, 17 May 2022 16:28:30 +0300 Subject: [PATCH 051/349] Enhance reply attack to prevent DUPLICATED_MESSAGE_INDEX while decrypting the same event --- .../crypto/replay_attack/ReplayAttackTest.kt | 160 ------------------ .../crypto/replayattack/ReplayAttackTest.kt | 109 ++++++++++++ .../sync/handler/room/RoomSyncHandler.kt | 9 +- 3 files changed, 117 insertions(+), 161 deletions(-) delete mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt deleted file mode 100644 index 5c9892e264..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2022 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.replay_attack - -import android.util.Log -import androidx.test.filters.LargeTest -import org.junit.Assert -import org.junit.Assert.assertEquals -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.runners.MethodSorters -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.Room -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings -import org.matrix.android.sdk.common.CommonTestHelper -import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.common.TestConstants - -@RunWith(JUnit4::class) -@FixMethodOrder(MethodSorters.JVM) -@LargeTest -class ReplayAttackTest : InstrumentedTest { - - @Test - fun replayAttackTest() { - val testHelper = CommonTestHelper(context()) - val cryptoTestHelper = CryptoTestHelper(testHelper) - val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) - - val e2eRoomID = cryptoTestData.roomId - - // Alice - val aliceSession = cryptoTestData.firstSession - val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! - - // Bob - val bobSession = cryptoTestData.secondSession - val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! - - assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) - Log.v("##REPLAY ATTACK", "Alice and Bob are in roomId: $e2eRoomID") - - - val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello", 20) - -// val aliceMessageId: String? = sendMessageInRoom(aliceRoomPOV, "Hello Bob, I am Alice!", testHelper) - Assert.assertTrue("Message should be sent", sentEvents.size == 20) - Log.v("##REPLAY ATTACK", "Alice sent message to roomId: $e2eRoomID") - - // Bob should be able to decrypt the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = bobSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) -// (timelineEvent != null && -// timelineEvent.isEncrypted() && -// timelineEvent.root.getClearType() == EventType.MESSAGE).also { -// if (it) { -// Log.v("#E2E TEST", "Bob can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") -// } -// } -// } -// } -// -// // Create a new user -// val arisSession = testHelper.createAccount("aris", SessionTestParams(true)) -// Log.v("#E2E TEST", "Aris user created") -// -// // Alice invites new user to the room -// testHelper.runBlockingTest { -// Log.v("#E2E TEST", "Alice invites ${arisSession.myUserId}") -// aliceRoomPOV.membershipService().invite(arisSession.myUserId) -// } -// -// waitForAndAcceptInviteInRoom(arisSession, e2eRoomID, testHelper) -// -// ensureMembersHaveJoined(aliceSession, arrayListOf(arisSession), e2eRoomID, testHelper) -// Log.v("#E2E TEST", "Aris has joined roomId: $e2eRoomID") -// -// when (roomHistoryVisibility) { -// RoomHistoryVisibility.WORLD_READABLE, -// RoomHistoryVisibility.SHARED, -// null -// -> { -// // Aris should be able to decrypt the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) -// (timelineEvent != null && -// timelineEvent.isEncrypted() && -// timelineEvent.root.getClearType() == EventType.MESSAGE -// ).also { -// if (it) { -// Log.v("#E2E TEST", "Aris can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") -// } -// } -// } -// } -// } -// RoomHistoryVisibility.INVITED, -// RoomHistoryVisibility.JOINED -> { -// // Aris should not even be able to get the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID) -// ?.timelineService() -// ?.getTimelineEvent(aliceMessageId!!) -// timelineEvent == null -// } -// } -// } -// } - -// testHelper.signOutAndClose(arisSession) - cryptoTestData.cleanUp(testHelper) - } - - private fun sendMessageInRoom(aliceRoomPOV: Room, text: String, testHelper: CommonTestHelper): String? { - aliceRoomPOV.sendService().sendTextMessage(text) - var sentEventId: String? = null - testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch -> - val timeline = aliceRoomPOV.timelineService().createTimeline(null, TimelineSettings(60)) - timeline.start() - testHelper.retryPeriodicallyWithLatch(latch) { - val decryptedMsg = timeline.getSnapshot() - .filter { it.root.getClearType() == EventType.MESSAGE } - .also { list -> - val message = list.joinToString(",", "[", "]") { "${it.root.type}|${it.root.sendState}" } - Log.v("#E2E TEST", "Timeline snapshot is $message") - } - .filter { it.root.sendState == SendState.SYNCED } - .firstOrNull { it.root.getClearContent().toModel()?.body?.startsWith(text) == true } - sentEventId = decryptedMsg?.eventId - decryptedMsg != null - } - - timeline.dispose() - } - return sentEventId - } -} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt new file mode 100644 index 0000000000..cb672f5e8d --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.replayattack + +import androidx.test.filters.LargeTest +import org.amshove.kluent.internal.assertFailsWith +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper + +@RunWith(JUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +@LargeTest +class ReplayAttackTest : InstrumentedTest { + + @Test + fun replayAttackAlreadyDecryptedEventTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + + // Alice will send a message + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) + Assert.assertTrue("Message should be sent", sentEvents.size == 1) + + val fakeEventId = sentEvents[0].eventId + "_fake" + val fakeEventWithTheSameIndex = + sentEvents[0].copy(eventId = fakeEventId, root = sentEvents[0].root.copy(eventId = fakeEventId)) + + testHelper.runBlockingTest { + // Lets assume we are from the main timelineId + val timelineId = "timelineId" + // Lets decrypt the original event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + // Lets decrypt the fake event that will have the same message index + val exception = assertFailsWith { + // An exception should be thrown while the same index would have been used for the previous decryption + aliceSession.cryptoService().decryptEvent(fakeEventWithTheSameIndex.root, timelineId) + } + assertEquals(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, exception.errorType) + } + cryptoTestData.cleanUp(testHelper) + } + + @Test + fun replayAttackSameEventTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + + // Alice will send a message + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) + Assert.assertTrue("Message should be sent", sentEvents.size == 1) + + testHelper.runBlockingTest { + // Lets assume we are from the main timelineId + val timelineId = "timelineId" + // Lets decrypt the original event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + // Lets try to decrypt the same event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + } + cryptoTestData.cleanUp(testHelper) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index a3be8b56a1..879bde1862 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.initsync.InitSyncStep @@ -520,9 +521,10 @@ internal class RoomSyncHandler @Inject constructor( private fun decryptIfNeeded(event: Event, roomId: String) { try { + val timelineId = generateTimelineId(roomId, event) // Event from sync does not have roomId, so add it to the event first // note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching - val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), "") } + val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId) } event.mxDecryptionResult = OlmDecryptionResult( payload = result.clearEvent, senderKey = result.senderCurve25519Key, @@ -537,6 +539,11 @@ internal class RoomSyncHandler @Inject constructor( } } + private fun generateTimelineId(roomId: String, event: Event): String { + val threadIndicator = if (event.isThread()) "_thread_" else "_" + return "${RoomSyncHandler::class.java.simpleName}$threadIndicator$roomId" + } + data class EphemeralResult( val typingUserIds: List = emptyList() ) From abbc57429a7a38d9ff5e3e091ddbe93f39e03196 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Tue, 17 May 2022 17:16:27 +0300 Subject: [PATCH 052/349] Add changelog --- changelog.d/6077.sdk | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6077.sdk diff --git a/changelog.d/6077.sdk b/changelog.d/6077.sdk new file mode 100644 index 0000000000..80310a28f5 --- /dev/null +++ b/changelog.d/6077.sdk @@ -0,0 +1 @@ +Improve replay attacks and reduce duplicate message index errors From 03acf4505acba15f48ae9e8783829aa4087e0c61 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 17 May 2022 18:03:34 +0200 Subject: [PATCH 053/349] Uses second layout to center room summary item title --- .../home/room/list/RoomSummaryItem.kt | 7 - .../home/room/list/RoomSummaryItemCentered.kt | 134 +++++++++++++++ .../home/room/list/RoomSummaryItemFactory.kt | 91 ++++++++--- vector/src/main/res/layout/item_room.xml | 18 +-- .../main/res/layout/item_room_centered.xml | 152 ++++++++++++++++++ 5 files changed, 355 insertions(+), 47 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt create mode 100644 vector/src/main/res/layout/item_room_centered.xml diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index abcfe0d5d8..5452b03992 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -19,7 +19,6 @@ package im.vector.app.features.home.room.list import android.view.HapticFeedbackConstants import android.view.View import android.widget.ImageView -import android.widget.Space import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible @@ -141,11 +140,6 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { private fun renderForFilteredDisplayMode(holder: Holder) { holder.subtitleView.text = subtitle - holder.centerTitle(shouldCenter = subtitle.isEmpty()) - } - - private fun Holder.centerTitle(shouldCenter: Boolean) { - centerTitleSpace.isVisible = shouldCenter } override fun unbind(holder: Holder) { @@ -182,6 +176,5 @@ abstract class RoomSummaryItem : VectorEpoxyModel() { val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) val rootView by bind(R.id.itemRoomLayout) - val centerTitleSpace by bind(R.id.centerTitleSpace) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt new file mode 100644 index 0000000000..8f2d949178 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemCentered.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list + +import android.view.HapticFeedbackConstants +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.amulyakhare.textdrawable.TextDrawable +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.ui.views.PresenceStateImageView +import im.vector.app.core.ui.views.ShieldImageView +import im.vector.app.features.displayname.getBestName +import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.RoomListDisplayMode +import im.vector.app.features.themes.ThemeUtils +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.presence.model.UserPresence +import org.matrix.android.sdk.api.util.MatrixItem + +@EpoxyModelClass(layout = R.layout.item_room_centered) +abstract class RoomSummaryItemCentered : VectorEpoxyModel() { + + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var matrixItem: MatrixItem + + @EpoxyAttribute + var displayMode: RoomListDisplayMode = RoomListDisplayMode.PEOPLE + + @EpoxyAttribute + var encryptionTrustLevel: RoomEncryptionTrustLevel? = null + + @EpoxyAttribute + var userPresence: UserPresence? = null + + @EpoxyAttribute + var showPresence: Boolean = false + + @EpoxyAttribute @JvmField + var isPublic: Boolean = false + + @EpoxyAttribute + var unreadNotificationCount: Int = 0 + + @EpoxyAttribute + var hasUnreadMessage: Boolean = false + + @EpoxyAttribute + var hasDraft: Boolean = false + + @EpoxyAttribute + var hasFailedSending: Boolean = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemLongClickListener: View.OnLongClickListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var itemClickListener: ClickListener? = null + + @EpoxyAttribute + var showSelected: Boolean = false + + override fun bind(holder: Holder) { + super.bind(holder) + + holder.rootView.onClick(itemClickListener) + holder.rootView.setOnLongClickListener { + it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS) + itemLongClickListener?.onLongClick(it) ?: false + } + holder.titleView.text = matrixItem.getBestName() + avatarRenderer.render(matrixItem, holder.avatarImageView) + holder.roomAvatarDecorationImageView.render(encryptionTrustLevel) + holder.roomAvatarPublicDecorationImageView.isVisible = isPublic + holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending + renderSelection(holder, showSelected) + holder.roomAvatarPresenceImageView.render(showPresence, userPresence) + } + + override fun unbind(holder: Holder) { + holder.rootView.setOnClickListener(null) + holder.rootView.setOnLongClickListener(null) + avatarRenderer.clear(holder.avatarImageView) + super.unbind(holder) + } + + private fun renderSelection(holder: Holder, isSelected: Boolean) { + if (isSelected) { + holder.avatarCheckedImageView.visibility = View.VISIBLE + val backgroundColor = ThemeUtils.getColor(holder.view.context, R.attr.colorPrimary) + val backgroundDrawable = TextDrawable.builder().buildRound("", backgroundColor) + holder.avatarImageView.setImageDrawable(backgroundDrawable) + } else { + holder.avatarCheckedImageView.visibility = View.GONE + avatarRenderer.render(matrixItem, holder.avatarImageView) + } + } + + class Holder : VectorEpoxyHolder() { + val titleView by bind(R.id.roomNameView) + val avatarCheckedImageView by bind(R.id.roomAvatarCheckedImageView) + val avatarImageView by bind(R.id.roomAvatarImageView) + val roomAvatarDecorationImageView by bind(R.id.roomAvatarDecorationImageView) + val roomAvatarPublicDecorationImageView by bind(R.id.roomAvatarPublicDecorationImageView) + val roomAvatarFailSendingImageView by bind(R.id.roomAvatarFailSendingImageView) + val roomAvatarPresenceImageView by bind(R.id.roomAvatarPresenceImageView) + val rootView by bind(R.id.itemRoomLayout) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 05701b908f..792303eaf6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -126,31 +126,74 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor } val typingMessage = typingHelper.getTypingMessage(roomSummary.typingUsers) - return RoomSummaryItem_() - .id(roomSummary.roomId) - .avatarRenderer(avatarRenderer) - // We do not display shield in the room list anymore - // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) - .displayMode(displayMode) - .subtitle(subtitle) - .isPublic(roomSummary.isPublic) - .showPresence(roomSummary.isDirect) - .userPresence(roomSummary.directUserPresence) - .matrixItem(roomSummary.toMatrixItem()) - .lastEventTime(latestEventTime) - .typingMessage(typingMessage) - .lastFormattedEvent(latestFormattedEvent.toEpoxyCharSequence()) - .showHighlighted(showHighlighted) - .showSelected(showSelected) - .hasFailedSending(roomSummary.hasFailedSending) - .unreadNotificationCount(unreadCount) - .hasUnreadMessage(roomSummary.hasUnreadMessages) - .hasDraft(roomSummary.userDrafts.isNotEmpty()) - .itemLongClickListener { _ -> - onLongClick?.invoke(roomSummary) ?: false - } - .itemClickListener { onClick?.invoke(roomSummary) } + + return if (subtitle.isBlank() && displayMode == RoomListDisplayMode.FILTERED) { + createCenteredRoomSummaryItem(roomSummary, displayMode, showSelected, unreadCount, onClick, onLongClick) + } else { + createRoomSummaryItem(roomSummary, displayMode, subtitle, latestEventTime, typingMessage, + latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick) + } } + + private fun createRoomSummaryItem( + roomSummary: RoomSummary, + displayMode: RoomListDisplayMode, + subtitle: String, + latestEventTime: String, + typingMessage: String, + latestFormattedEvent: CharSequence, + showHighlighted: Boolean, + showSelected: Boolean, + unreadCount: Int, + onClick: ((RoomSummary) -> Unit)?, + onLongClick: ((RoomSummary) -> Boolean)? + ) = RoomSummaryItem_() + .id(roomSummary.roomId) + .avatarRenderer(avatarRenderer) + // We do not display shield in the room list anymore + // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .subtitle(subtitle) + .isPublic(roomSummary.isPublic) + .showPresence(roomSummary.isDirect) + .userPresence(roomSummary.directUserPresence) + .matrixItem(roomSummary.toMatrixItem()) + .lastEventTime(latestEventTime) + .typingMessage(typingMessage) + .lastFormattedEvent(latestFormattedEvent.toEpoxyCharSequence()) + .showHighlighted(showHighlighted) + .showSelected(showSelected) + .hasFailedSending(roomSummary.hasFailedSending) + .unreadNotificationCount(unreadCount) + .hasUnreadMessage(roomSummary.hasUnreadMessages) + .hasDraft(roomSummary.userDrafts.isNotEmpty()) + .itemLongClickListener { _ -> onLongClick?.invoke(roomSummary) ?: false } + .itemClickListener { onClick?.invoke(roomSummary) } + + private fun createCenteredRoomSummaryItem( + roomSummary: RoomSummary, + displayMode: RoomListDisplayMode, + showSelected: Boolean, + unreadCount: Int, + onClick: ((RoomSummary) -> Unit)?, + onLongClick: ((RoomSummary) -> Boolean)? + ) = RoomSummaryItemCentered_() + .id(roomSummary.roomId) + .avatarRenderer(avatarRenderer) + // We do not display shield in the room list anymore + // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) + .displayMode(displayMode) + .isPublic(roomSummary.isPublic) + .showPresence(roomSummary.isDirect) + .userPresence(roomSummary.directUserPresence) + .matrixItem(roomSummary.toMatrixItem()) + .showSelected(showSelected) + .hasFailedSending(roomSummary.hasFailedSending) + .unreadNotificationCount(unreadCount) + .hasUnreadMessage(roomSummary.hasUnreadMessages) + .hasDraft(roomSummary.userDrafts.isNotEmpty()) + .itemLongClickListener { _ -> onLongClick?.invoke(roomSummary) ?: false } + .itemClickListener { onClick?.invoke(roomSummary) } private fun getSearchResultSubtitle(roomSummary: RoomSummary): String { val userId = roomSummary.directUserId diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index ac028ccb08..ab0af18acb 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -112,27 +112,13 @@ app:layout_constraintTop_toBottomOf="@id/roomAvatarContainer" tools:layout_marginStart="20dp" /> - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d12ab175163fe4f8e58a0c25cc941c042aaf0848 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 18 May 2022 11:29:23 +0200 Subject: [PATCH 054/349] Fixes lint errors --- .../app/features/home/room/list/RoomSummaryItemFactory.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index 792303eaf6..3f29c1d14c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -130,11 +130,13 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor return if (subtitle.isBlank() && displayMode == RoomListDisplayMode.FILTERED) { createCenteredRoomSummaryItem(roomSummary, displayMode, showSelected, unreadCount, onClick, onLongClick) } else { - createRoomSummaryItem(roomSummary, displayMode, subtitle, latestEventTime, typingMessage, - latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick) + createRoomSummaryItem( + roomSummary, displayMode, subtitle, latestEventTime, typingMessage, + latestFormattedEvent, showHighlighted, showSelected, unreadCount, onClick, onLongClick + ) } } - + private fun createRoomSummaryItem( roomSummary: RoomSummary, displayMode: RoomListDisplayMode, From b9adbb7d60bee6a09163c24678610206edc85f48 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Wed, 18 May 2022 14:05:58 +0300 Subject: [PATCH 055/349] PR remarks --- .../crypto/replayattack/ReplayAttackTest.kt | 9 ++++++-- .../sdk/internal/crypto/MXOlmDevice.kt | 21 ++++++------------- .../sync/handler/room/RoomSyncHandler.kt | 8 +++---- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt index cb672f5e8d..69be4a3678 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -20,6 +20,7 @@ import androidx.test.filters.LargeTest import org.amshove.kluent.internal.assertFailsWith import org.junit.Assert import org.junit.Assert.assertEquals +import org.junit.Assert.fail import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -101,8 +102,12 @@ class ReplayAttackTest : InstrumentedTest { val timelineId = "timelineId" // Lets decrypt the original event aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) - // Lets try to decrypt the same event - aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + try { + // Lets try to decrypt the same event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + } catch (ex: Throwable) { + fail("Shouldn't throw a decryption error for same event") + } } cryptoTestData.cleanUp(testHelper) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 16e6bb173d..87384b3fe2 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -96,10 +96,9 @@ internal class MXOlmDevice @Inject constructor( // So, store these message indexes per timeline id. // // The first level keys are timeline ids. - // The second level keys are strings of form "||" - private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() - - private val replayAttackMap: MutableMap = HashMap() + // The second level values is a Map that represents: + // "|||" --> eventId + private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() init { // Retrieve the account from the store @@ -798,15 +797,14 @@ internal class MXOlmDevice @Inject constructor( Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") if (timeline?.isNotBlank() == true) { - val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } - if (timelineSet.contains(messageIndexKey) && messageIndexKey.alreadyUsed(eventId)) { + val replayAttackMap = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableMapOf() } + if (replayAttackMap.contains(messageIndexKey) && replayAttackMap[messageIndexKey] != eventId) { val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) } - timelineSet.add(messageIndexKey) + replayAttackMap[messageIndexKey] = eventId } - replayAttackMap[messageIndexKey] = eventId inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) val payload = try { val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) @@ -825,13 +823,6 @@ internal class MXOlmDevice @Inject constructor( ) } - /** - * Determines whether or not the messageKey has already been used to decrypt another eventId - */ - private fun String.alreadyUsed(eventId: String): Boolean { - return replayAttackMap[this] != null && replayAttackMap[this] != eventId - } - /** * Reset replay attack data for the given timeline. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 879bde1862..cf916dc907 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.initsync.InitSyncStep @@ -521,7 +520,7 @@ internal class RoomSyncHandler @Inject constructor( private fun decryptIfNeeded(event: Event, roomId: String) { try { - val timelineId = generateTimelineId(roomId, event) + val timelineId = generateTimelineId(roomId) // Event from sync does not have roomId, so add it to the event first // note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId) } @@ -539,9 +538,8 @@ internal class RoomSyncHandler @Inject constructor( } } - private fun generateTimelineId(roomId: String, event: Event): String { - val threadIndicator = if (event.isThread()) "_thread_" else "_" - return "${RoomSyncHandler::class.java.simpleName}$threadIndicator$roomId" + private fun generateTimelineId(roomId: String): String { + return "${RoomSyncHandler::class.java.simpleName}$roomId" } data class EphemeralResult( From 5532e7dfa1c69969394cb7aa9f333b063c17218b Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Wed, 18 May 2022 14:57:50 +0300 Subject: [PATCH 056/349] Fix copyright --- .../sdk/internal/crypto/replayattack/ReplayAttackTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt index 69be4a3678..9932375ed2 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 388e35e828afcea811156f1959763107fd1b04e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Wed, 18 May 2022 14:19:11 +0200 Subject: [PATCH 057/349] Remove even more deps --- build.gradle | 4 +++- library/jsonviewer/build.gradle | 2 +- matrix-sdk-android-flow/build.gradle | 3 --- vector-config/build.gradle | 4 ---- vector/build.gradle | 1 - 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index cf49f37809..79637f9756 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,9 @@ plugins { id "org.jlleitschuh.gradle.ktlint" version "10.3.0" // Detekt id "io.gitlab.arturbosch.detekt" version "1.20.0" - id 'com.autonomousapps.dependency-analysis' version "1.0.0" + + // Dependency Analysis + id 'com.autonomousapps.dependency-analysis' version "1.2.1" } // https://github.com/jeremylong/DependencyCheck diff --git a/library/jsonviewer/build.gradle b/library/jsonviewer/build.gradle index 2110747feb..e1a3b0c9ee 100644 --- a/library/jsonviewer/build.gradle +++ b/library/jsonviewer/build.gradle @@ -52,6 +52,7 @@ dependencies { implementation libs.androidx.appCompat implementation libs.androidx.core + implementation libs.androidx.recyclerview implementation libs.airbnb.epoxy kapt libs.airbnb.epoxyProcessor @@ -60,7 +61,6 @@ dependencies { // Span utils implementation 'me.gujun.android:span:1.7' - implementation libs.google.material implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid diff --git a/matrix-sdk-android-flow/build.gradle b/matrix-sdk-android-flow/build.gradle index fb69af2d82..6385e66abb 100644 --- a/matrix-sdk-android-flow/build.gradle +++ b/matrix-sdk-android-flow/build.gradle @@ -36,7 +36,4 @@ dependencies { implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid implementation libs.androidx.lifecycleLivedata - - // Paging - implementation libs.androidx.pagingRuntimeKtx } diff --git a/vector-config/build.gradle b/vector-config/build.gradle index 4156e74274..95b6a6215d 100644 --- a/vector-config/build.gradle +++ b/vector-config/build.gradle @@ -1,6 +1,5 @@ plugins { id 'com.android.library' - id 'org.jetbrains.kotlin.android' } android { @@ -14,7 +13,4 @@ android { sourceCompatibility versions.sourceCompat targetCompatibility versions.targetCompat } - kotlinOptions { - jvmTarget = "11" - } } diff --git a/vector/build.gradle b/vector/build.gradle index c91b7b50b7..1c0a4718c4 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -370,7 +370,6 @@ dependencies { implementation libs.androidx.lifecycleProcess implementation libs.androidx.lifecycleRuntimeKtx - implementation libs.androidx.datastore implementation libs.androidx.datastorepreferences From b2765e4b63613168a0c1c8a855e2ea2d02689566 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 14:29:50 +0200 Subject: [PATCH 058/349] Adding changelog entry --- changelog.d/6012.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6012.wip diff --git a/changelog.d/6012.wip b/changelog.d/6012.wip new file mode 100644 index 0000000000..9c67d562fe --- /dev/null +++ b/changelog.d/6012.wip @@ -0,0 +1 @@ +Live location sharing: navigation from timeline to map screen From 52c0fa41c6ce56555dbc987703ddc6edd62d420c Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 16:49:27 +0200 Subject: [PATCH 059/349] Creation of map view screen and basic navigation --- vector/src/main/AndroidManifest.xml | 1 + .../im/vector/app/core/di/FragmentModule.kt | 6 ++ .../home/room/detail/TimelineFragment.kt | 12 +++ .../live/map/LocationLiveMapViewActivity.kt | 68 +++++++++++++ .../live/map/LocationLiveMapViewFragment.kt | 99 +++++++++++++++++++ .../features/navigation/DefaultNavigator.kt | 10 ++ .../app/features/navigation/Navigator.kt | 2 + 7 files changed, 198 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 20b7c4908a..fc78ce90a3 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -343,6 +343,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index c68a35f4e5..6d42c83ac2 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,6 +64,7 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment +import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -993,4 +994,9 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LocationLiveMapViewFragment::class) + fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2bb620623c..bf7c506d79 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -221,6 +221,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent +import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageFormat import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent @@ -647,6 +648,13 @@ class TimelineFragment @Inject constructor( ) } + private fun navigateToLocationLiveMap() { + navigator.openLocationLiveMap( + context = requireContext(), + roomId = timelineArgs.roomId + ) + } + private fun handleChangeLocationIndicator(event: RoomDetailViewEvents.ChangeLocationIndicator) { views.locationLiveStatusIndicator.isVisible = event.isVisible } @@ -2015,6 +2023,10 @@ class TimelineFragment @Inject constructor( is MessageLocationContent -> { handleShowLocationPreview(messageContent, informationData.senderId) } + is MessageBeaconInfoContent -> { + // TODO navigate only from running live location message: possible after merge of associated PR + navigateToLocationLiveMap() + } else -> { val handled = onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) if (!handled) { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt new file mode 100644 index 0000000000..cb54e93f97 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.content.Context +import android.content.Intent +import android.os.Parcelable +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityLocationSharingBinding +import kotlinx.parcelize.Parcelize + +@Parcelize +data class LocationLiveMapViewArgs( + val roomId: String +) : Parcelable + +@AndroidEntryPoint +class LocationLiveMapViewActivity : VectorBaseActivity() { + + override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) + + override fun initUiAndData() { + val mapViewArgs: LocationLiveMapViewArgs? = intent?.extras?.getParcelable(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS) + if (mapViewArgs == null) { + finish() + return + } + setupToolbar(views.toolbar) + // TODO check what should be the title and create String resource + .setTitle("Live") + .allowBack() + + if (isFirstCreation()) { + addFragment( + views.fragmentContainer, + LocationLiveMapViewFragment::class.java, + mapViewArgs + ) + } + } + + companion object { + + private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" + + fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { + return Intent(context, LocationLiveMapViewActivity::class.java).apply { + putExtra(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS, locationLiveMapViewArgs) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt new file mode 100644 index 0000000000..7e17712556 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.args +import com.mapbox.mapboxsdk.maps.MapView +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentLocationPreviewBinding +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.location.UrlMapProvider +import java.lang.ref.WeakReference +import javax.inject.Inject + +/** + * Screen showing a map with all the current users sharing their live location in room. + */ +class LocationLiveMapViewFragment @Inject constructor( + private val urlMapProvider: UrlMapProvider, + private val locationPinProvider: LocationPinProvider +) : VectorBaseFragment() { + + // TODO use a SupportMapFragment with FragmentManager + // TODO align design with Figma + + private val args: LocationLiveMapViewArgs by args() + + // Keep a ref to handle properly the onDestroy callback + private var mapView: WeakReference? = null + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationPreviewBinding { + return FragmentLocationPreviewBinding.inflate(layoutInflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + mapView = WeakReference(views.mapView) + views.mapView.onCreate(savedInstanceState) + + lifecycleScope.launchWhenCreated { + views.mapView.initialize(urlMapProvider.getMapUrl()) + } + } + + override fun onResume() { + super.onResume() + views.mapView.onResume() + } + + override fun onPause() { + views.mapView.onPause() + super.onPause() + } + + override fun onLowMemory() { + views.mapView.onLowMemory() + super.onLowMemory() + } + + override fun onStart() { + super.onStart() + views.mapView.onStart() + } + + override fun onStop() { + views.mapView.onStop() + super.onStop() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + views.mapView.onSaveInstanceState(outState) + } + + override fun onDestroy() { + mapView?.get()?.onDestroy() + mapView?.clear() + super.onDestroy() + } +} diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 7cc42ec57f..1ec4011289 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -68,6 +68,8 @@ import im.vector.app.features.location.LocationData import im.vector.app.features.location.LocationSharingActivity import im.vector.app.features.location.LocationSharingArgs import im.vector.app.features.location.LocationSharingMode +import im.vector.app.features.location.live.map.LocationLiveMapViewActivity +import im.vector.app.features.location.live.map.LocationLiveMapViewArgs import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.matrixto.MatrixToBottomSheet @@ -591,6 +593,14 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } + override fun openLocationLiveMap(context: Context, roomId: String) { + val intent = LocationLiveMapViewActivity.getIntent( + context = context, + locationLiveMapViewArgs = LocationLiveMapViewArgs(roomId = roomId) + ) + context.startActivity(intent) + } + private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) { if (buildTask) { val stackBuilder = TaskStackBuilder.create(context) diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 075b41daf3..d4ef2b8099 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -172,6 +172,8 @@ interface Navigator { initialLocationData: LocationData?, locationOwnerId: String?) + fun openLocationLiveMap(context: Context, roomId: String) + fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs, eventIdToNavigate: String? = null) fun openThreadList(context: Context, threadTimelineArgs: ThreadTimelineArgs) From 54d7d47dfcda4fac17b3df81703a9229df2fcddd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 17:27:41 +0200 Subject: [PATCH 060/349] Updating the title of the map view screen --- .../features/location/live/map/LocationLiveMapViewActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index cb54e93f97..c0f07dba57 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Parcelable import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding @@ -42,8 +43,7 @@ class LocationLiveMapViewActivity : VectorBaseActivity Date: Wed, 11 May 2022 09:37:25 +0200 Subject: [PATCH 061/349] Use SupportMapFragment instead of custom fragment --- .../im/vector/app/core/di/FragmentModule.kt | 6 -- .../im/vector/app/core/extensions/Activity.kt | 6 +- .../live/map/LocationLiveMapViewActivity.kt | 34 +++++-- .../live/map/LocationLiveMapViewFragment.kt | 99 ------------------- 4 files changed, 32 insertions(+), 113 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 6d42c83ac2..c68a35f4e5 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,7 +64,6 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment -import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -994,9 +993,4 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LocationLiveMapViewFragment::class) - fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index 6f2ea9699a..cbdf5e3573 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -39,8 +39,10 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult) fun AppCompatActivity.addFragment( container: ViewGroup, fragment: Fragment, - allowStateLoss: Boolean = false) { - supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment) } + allowStateLoss: Boolean = false, + tag: String? = null +) { + supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment, tag) } } fun AppCompatActivity.addFragment( diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index c0f07dba57..41e08dc655 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -19,21 +19,31 @@ package im.vector.app.features.location.live.map import android.content.Context import android.content.Intent import android.os.Parcelable +import androidx.lifecycle.lifecycleScope +import com.mapbox.mapboxsdk.maps.MapboxMapOptions +import com.mapbox.mapboxsdk.maps.SupportMapFragment import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding +import im.vector.app.features.location.UrlMapProvider import kotlinx.parcelize.Parcelize +import javax.inject.Inject @Parcelize data class LocationLiveMapViewArgs( val roomId: String ) : Parcelable +/** + * Screen showing a map with all the current users sharing their live location in room. + */ @AndroidEntryPoint class LocationLiveMapViewActivity : VectorBaseActivity() { + @Inject lateinit var urlMapProvider: UrlMapProvider + override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) override fun initUiAndData() { @@ -46,18 +56,30 @@ class LocationLiveMapViewActivity : VectorBaseActivity + lifecycleScope.launchWhenCreated { + mapBoxMap.setStyle(urlMapProvider.getMapUrl()) + } } } companion object { private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" + private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { return Intent(context, LocationLiveMapViewActivity::class.java).apply { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt deleted file mode 100644 index 7e17712556..0000000000 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2022 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.features.location.live.map - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.lifecycle.lifecycleScope -import com.airbnb.mvrx.args -import com.mapbox.mapboxsdk.maps.MapView -import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.databinding.FragmentLocationPreviewBinding -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider -import im.vector.app.features.location.UrlMapProvider -import java.lang.ref.WeakReference -import javax.inject.Inject - -/** - * Screen showing a map with all the current users sharing their live location in room. - */ -class LocationLiveMapViewFragment @Inject constructor( - private val urlMapProvider: UrlMapProvider, - private val locationPinProvider: LocationPinProvider -) : VectorBaseFragment() { - - // TODO use a SupportMapFragment with FragmentManager - // TODO align design with Figma - - private val args: LocationLiveMapViewArgs by args() - - // Keep a ref to handle properly the onDestroy callback - private var mapView: WeakReference? = null - - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationPreviewBinding { - return FragmentLocationPreviewBinding.inflate(layoutInflater, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - mapView = WeakReference(views.mapView) - views.mapView.onCreate(savedInstanceState) - - lifecycleScope.launchWhenCreated { - views.mapView.initialize(urlMapProvider.getMapUrl()) - } - } - - override fun onResume() { - super.onResume() - views.mapView.onResume() - } - - override fun onPause() { - views.mapView.onPause() - super.onPause() - } - - override fun onLowMemory() { - views.mapView.onLowMemory() - super.onLowMemory() - } - - override fun onStart() { - super.onStart() - views.mapView.onStart() - } - - override fun onStop() { - views.mapView.onStop() - super.onStop() - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - views.mapView.onSaveInstanceState(outState) - } - - override fun onDestroy() { - mapView?.get()?.onDestroy() - mapView?.clear() - super.onDestroy() - } -} From 23e8cad10f9f8435d847536f898f08cc06de5167 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 11 May 2022 16:53:13 +0200 Subject: [PATCH 062/349] Rollback to Fragment to be able to use Maverick capabilities --- .../im/vector/app/core/di/FragmentModule.kt | 6 ++ .../im/vector/app/core/extensions/Activity.kt | 6 +- .../im/vector/app/core/extensions/Fragment.kt | 3 +- .../live/map/LocationLiveMapViewActivity.kt | 34 ++------ .../live/map/LocationLiveMapViewFragment.kt | 77 +++++++++++++++++++ .../res/layout/fragment_live_location_map.xml | 5 ++ 6 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt create mode 100644 vector/src/main/res/layout/fragment_live_location_map.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index c68a35f4e5..6d42c83ac2 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,6 +64,7 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment +import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -993,4 +994,9 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LocationLiveMapViewFragment::class) + fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index cbdf5e3573..6f2ea9699a 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -39,10 +39,8 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult) fun AppCompatActivity.addFragment( container: ViewGroup, fragment: Fragment, - allowStateLoss: Boolean = false, - tag: String? = null -) { - supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment, tag) } + allowStateLoss: Boolean = false) { + supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment) } } fun AppCompatActivity.addFragment( diff --git a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt index dfbd2eba97..61c4fe2174 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt @@ -36,9 +36,10 @@ fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit): fun Fragment.addFragment( frameId: Int, fragment: Fragment, + tag: String? = null, allowStateLoss: Boolean = false ) { - parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) } + parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) } } fun Fragment.addFragment( diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index 41e08dc655..c0f07dba57 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -19,31 +19,21 @@ package im.vector.app.features.location.live.map import android.content.Context import android.content.Intent import android.os.Parcelable -import androidx.lifecycle.lifecycleScope -import com.mapbox.mapboxsdk.maps.MapboxMapOptions -import com.mapbox.mapboxsdk.maps.SupportMapFragment import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding -import im.vector.app.features.location.UrlMapProvider import kotlinx.parcelize.Parcelize -import javax.inject.Inject @Parcelize data class LocationLiveMapViewArgs( val roomId: String ) : Parcelable -/** - * Screen showing a map with all the current users sharing their live location in room. - */ @AndroidEntryPoint class LocationLiveMapViewActivity : VectorBaseActivity() { - @Inject lateinit var urlMapProvider: UrlMapProvider - override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) override fun initUiAndData() { @@ -56,30 +46,18 @@ class LocationLiveMapViewActivity : VectorBaseActivity - lifecycleScope.launchWhenCreated { - mapBoxMap.setStyle(urlMapProvider.getMapUrl()) - } + if (isFirstCreation()) { + addFragment( + views.fragmentContainer, + LocationLiveMapViewFragment::class.java, + mapViewArgs + ) } } companion object { private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" - private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { return Intent(context, LocationLiveMapViewActivity::class.java).apply { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt new file mode 100644 index 0000000000..29c45f8945 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.args +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMapOptions +import com.mapbox.mapboxsdk.maps.SupportMapFragment +import im.vector.app.R +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentLiveLocationMapBinding +import im.vector.app.databinding.FragmentLocationPreviewBinding +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.location.UrlMapProvider +import java.lang.ref.WeakReference +import javax.inject.Inject + +/** + * Screen showing a map with all the current users sharing their live location in room. + */ +class LocationLiveMapViewFragment @Inject constructor( + private val urlMapProvider: UrlMapProvider, + private val locationPinProvider: LocationPinProvider +) : VectorBaseFragment() { + + private val args: LocationLiveMapViewArgs by args() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLiveLocationMapBinding { + return FragmentLiveLocationMapBinding.inflate(layoutInflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupMap() + } + + private fun setupMap() { + val mapFragment: SupportMapFragment = + parentFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG) as? SupportMapFragment + ?: run { + val options = MapboxMapOptions.createFromAttributes(requireContext(), null) + val fragment = SupportMapFragment.newInstance(options) + addFragment(R.id.liveLocationMapContainer, fragment, tag = MAP_FRAGMENT_TAG) + fragment + } + + mapFragment.getMapAsync { mapBoxMap -> + lifecycleScope.launchWhenCreated { + mapBoxMap.setStyle(urlMapProvider.getMapUrl()) + } + } + } + + companion object { + private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" + } +} diff --git a/vector/src/main/res/layout/fragment_live_location_map.xml b/vector/src/main/res/layout/fragment_live_location_map.xml new file mode 100644 index 0000000000..5238508d6f --- /dev/null +++ b/vector/src/main/res/layout/fragment_live_location_map.xml @@ -0,0 +1,5 @@ + + From 4864980a5afd194fb5ce619b6c49c56ecebf0d32 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 17 May 2022 11:07:21 +0200 Subject: [PATCH 063/349] Enable navigation only from running state item --- .../app/features/home/room/detail/TimelineFragment.kt | 1 - .../timeline/factory/LiveLocationShareMessageItemFactory.kt | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index bf7c506d79..7ab3ab2adc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -2024,7 +2024,6 @@ class TimelineFragment @Inject constructor( handleShowLocationPreview(messageContent, informationData.senderId) } is MessageBeaconInfoContent -> { - // TODO navigate only from running live location message: possible after merge of associated PR navigateToLocationLiveMap() } else -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt index 479a742369..912702aaed 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt @@ -75,7 +75,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor( val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) return MessageLiveLocationInactiveItem_() - .attributes(attributes) + // disable the click on this state item + .attributes(attributes.copy(itemClickListener = null)) .mapWidth(width) .mapHeight(height) .highlighted(highlight) @@ -90,7 +91,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor( val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) return MessageLiveLocationStartItem_() - .attributes(attributes) + // disable the click on this state item + .attributes(attributes.copy(itemClickListener = null)) .mapWidth(width) .mapHeight(height) .highlighted(highlight) From 526585677234a063f4ebcbc9a88731fc1aeacb9b Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 17 May 2022 11:11:41 +0200 Subject: [PATCH 064/349] Remove unused imports --- .../location/live/map/LocationLiveMapViewFragment.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt index 29c45f8945..50526f2839 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -22,17 +22,13 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args -import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMapOptions import com.mapbox.mapboxsdk.maps.SupportMapFragment import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentLiveLocationMapBinding -import im.vector.app.databinding.FragmentLocationPreviewBinding -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider import im.vector.app.features.location.UrlMapProvider -import java.lang.ref.WeakReference import javax.inject.Inject /** @@ -40,7 +36,6 @@ import javax.inject.Inject */ class LocationLiveMapViewFragment @Inject constructor( private val urlMapProvider: UrlMapProvider, - private val locationPinProvider: LocationPinProvider ) : VectorBaseFragment() { private val args: LocationLiveMapViewArgs by args() From 6c569e6f9d1739dee15ceb9ff2859b8cdab18ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Wed, 18 May 2022 18:22:36 +0200 Subject: [PATCH 065/349] Bring back a false positive --- matrix-sdk-android-flow/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/matrix-sdk-android-flow/build.gradle b/matrix-sdk-android-flow/build.gradle index 6385e66abb..fb69af2d82 100644 --- a/matrix-sdk-android-flow/build.gradle +++ b/matrix-sdk-android-flow/build.gradle @@ -36,4 +36,7 @@ dependencies { implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid implementation libs.androidx.lifecycleLivedata + + // Paging + implementation libs.androidx.pagingRuntimeKtx } From 86663ec073870a2125e3f266761c5a9ed3ffc132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Wed, 18 May 2022 18:47:52 +0200 Subject: [PATCH 066/349] Fine tune dependency analysis, add CI workflow --- .github/workflows/quality.yml | 8 ++++++++ build.gradle | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index a97d532644..d7d3ceffcc 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -117,6 +117,8 @@ jobs: ${{ runner.os }}-gradle- - name: Lint analysis run: ./gradlew clean :vector:lint --stacktrace + - name: Dependency analysis + run: ./gradlew buildHealth - name: Upload reports if: always() uses: actions/upload-artifact@v3 @@ -124,6 +126,12 @@ jobs: name: lint-report path: | vector/build/reports/*.* + - name: Upload dependency analysis + if: always() + uses: actions/upload-artifact@v3 + with: + name: dependency-analysis + path: build/reports/dependency-analysis/build-health-report.txt # Lint for Gplay and Fdroid release APK apk-lint: diff --git a/build.gradle b/build.gradle index 79637f9756..fe71865ef1 100644 --- a/build.gradle +++ b/build.gradle @@ -234,7 +234,38 @@ dependencyAnalysis { } issues { all { - ignoreKtx(true) // default is false + ignoreKtx(true) + onUsedTransitiveDependencies { + // Transitively used dependencies that should be declared directly + severity("ignore") + } + onUnusedDependencies { + severity("fail") + } + onUnusedAnnotationProcessors { + severity("fail") + exclude("com.airbnb.android:epoxy-processor", "com.google.dagger:hilt-compiler") // False positives + } + } + project(":library:jsonviewer") { + onUnusedDependencies { + exclude("org.json:json") // Used in unit tests, overwrites the one bundled into Android + } + } + project(":library:ui-styles") { + onUnusedDependencies { + exclude("com.github.vector-im:PFLockScreen-Android") // False positive + } + } + project(":matrix-sdk-android") { + onUnusedDependencies { + exclude("io.reactivex.rxjava2:rxkotlin") // Transitively required for mocking realm as monarchy doesn't expose Rx + } + } + project(":matrix-sdk-android-flow") { + onUnusedDependencies { + exclude("androidx.paging:paging-runtime-ktx") // False positive + } } } } From 93264812c0cd07d93d26e1149adde918cba3a2a6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 19 May 2022 10:20:46 +0200 Subject: [PATCH 067/349] Adds back navigation to spaces --- .../java/im/vector/app/AppStateHandler.kt | 14 ++++++++++--- .../app/features/home/HomeDetailFragment.kt | 21 +++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index 1608d561bc..d44af53a55 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -72,6 +72,8 @@ class AppStateHandler @Inject constructor( val selectedRoomGroupingFlow = selectedSpaceDataSource.stream() + private val spaceBackstack = ArrayDeque() + fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? { // XXX we should somehow make it live :/ just a work around // For example just after creating a space and switching to it the @@ -87,12 +89,16 @@ class AppStateHandler @Inject constructor( } } - fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false) { + fun setCurrentSpace(spaceId: String?, session: Session? = null, persistNow: Boolean = false, isForwardNavigation: Boolean = true) { + val currentSpace = (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.space() val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return - if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace && - spaceId == selectedSpaceDataSource.currentValue?.orNull()?.space()?.roomId) return + if (currentSpace != null && spaceId == currentSpace.roomId) return val spaceSum = spaceId?.let { uSession.getRoomSummary(spaceId) } + if (isForwardNavigation) { + spaceBackstack.addLast(currentSpace?.roomId) + } + if (persistNow) { uiStateRepository.storeGroupingMethod(true, uSession.sessionId) uiStateRepository.storeSelectedSpace(spaceSum?.roomId, uSession.sessionId) @@ -151,6 +157,8 @@ class AppStateHandler @Inject constructor( }.launchIn(session.coroutineScope) } + fun getSpaceBackstack() = spaceBackstack + fun safeActiveSpaceId(): String? { return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index f7266db214..213c9fe193 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -146,7 +146,7 @@ class HomeDetailFragment @Inject constructor( } views.groupToolbarNavigateUp.setOnClickListener { - navigateUpOneSpace() + navigateBack() } viewModel.observeViewEvents { viewEvent -> @@ -191,10 +191,23 @@ class HomeDetailFragment @Inject constructor( } } + private fun navigateBack() { + try { + val lastSpace = appStateHandler.getSpaceBackstack().removeLast() + setCurrentSpace(lastSpace) + } catch (e: NoSuchElementException) { + navigateUpOneSpace() + } + } + + private fun setCurrentSpace(spaceId: String?) { + appStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false) + sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup) + } + private fun navigateUpOneSpace() { val parentId = getCurrentSpace()?.flattenParentIds?.lastOrNull() - appStateHandler.setCurrentSpace(parentId) - sharedActionViewModel.post(HomeActivitySharedAction.CloseGroup) + setCurrentSpace(parentId) } private fun getCurrentSpace() = (appStateHandler.getCurrentRoomGroupingMethod() as? RoomGroupingMethod.BySpace)?.spaceSummary @@ -495,7 +508,7 @@ class HomeDetailFragment @Inject constructor( } override fun onBackPressed(toolbarButton: Boolean) = if (getCurrentSpace() != null) { - navigateUpOneSpace() + navigateBack() true } else { false From c093b3476fc2a790fbefb4aaeef68f943f450d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 19 May 2022 10:57:06 +0200 Subject: [PATCH 068/349] Limit parallel Gradle tasks --- .github/workflows/quality.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index d7d3ceffcc..8b3d966e9b 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -118,7 +118,7 @@ jobs: - name: Lint analysis run: ./gradlew clean :vector:lint --stacktrace - name: Dependency analysis - run: ./gradlew buildHealth + run: ./gradlew buildHealth --max-workers=1 - name: Upload reports if: always() uses: actions/upload-artifact@v3 From 464735f82995fce3657bb9a5c741591da4158e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 19 May 2022 11:31:32 +0200 Subject: [PATCH 069/349] Move dependency analysis to its own job --- .github/workflows/quality.yml | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 8b3d966e9b..d51d732a3b 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -97,6 +97,25 @@ jobs: comment_id: ${{ steps.fc.outputs.comment-id }} }) +# Gradle dependency analysis using https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin + dependency-analysis: + name: Dependency analysis + 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) }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v3 + - name: Dependency analysis + run: ./gradlew buildHealth --max-workers=1 + - name: Upload dependency analysis + if: always() + uses: actions/upload-artifact@v3 + with: + name: dependency-analysis + path: build/reports/dependency-analysis/build-health-report.txt + # Lint for main module android-lint: name: Android Linter @@ -117,8 +136,6 @@ jobs: ${{ runner.os }}-gradle- - name: Lint analysis run: ./gradlew clean :vector:lint --stacktrace - - name: Dependency analysis - run: ./gradlew buildHealth --max-workers=1 - name: Upload reports if: always() uses: actions/upload-artifact@v3 @@ -126,12 +143,6 @@ jobs: name: lint-report path: | vector/build/reports/*.* - - name: Upload dependency analysis - if: always() - uses: actions/upload-artifact@v3 - with: - name: dependency-analysis - path: build/reports/dependency-analysis/build-health-report.txt # Lint for Gplay and Fdroid release APK apk-lint: From 28c4abb505930d649b76a83930d847ca277ad424 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 10:34:38 +0100 Subject: [PATCH 070/349] Track number of retries of tests, and retry KeysBackupTest --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 3 +++ .../android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index b16ab98e6c..80ccf578e5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,6 +40,9 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() + if(i > 0) { + println("Retried test $i times") + } return } catch (t: Throwable) { caughtThrowable = t diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 9136272b1e..d5fd299f1f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -24,6 +24,7 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.FixMethodOrder +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -45,6 +46,7 @@ import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback import java.util.Collections @@ -55,6 +57,8 @@ import java.util.concurrent.CountDownLatch @LargeTest class KeysBackupTest : InstrumentedTest { + @get:Rule val rule = RetryTestRule(3) + /** * - From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys * - Check backup keys after having marked one as backed up From bc050d303044af1b42c5f5aada9a7ce0bb97fec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 19 May 2022 12:08:17 +0200 Subject: [PATCH 071/349] Tweak JVM memory settings --- .github/workflows/quality.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index d51d732a3b..84823906c7 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -5,6 +5,12 @@ on: push: branches: [ main, develop ] +# Enrich gradle.properties for CI/CD +env: + CI_GRADLE_ARG_PROPERTIES: > + -Porg.gradle.jvmargs=-Xmx4g + -Porg.gradle.parallel=false + jobs: check: name: Project Check Suite @@ -108,7 +114,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Dependency analysis - run: ./gradlew buildHealth --max-workers=1 + run: ./gradlew buildHealth $CI_GRADLE_ARG_PROPERTIES - name: Upload dependency analysis if: always() uses: actions/upload-artifact@v3 From 429094511897178045023f443a2eb541714f6b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 19 May 2022 12:09:45 +0200 Subject: [PATCH 072/349] Enable parallelism --- .github/workflows/quality.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 84823906c7..ae6af06d86 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -9,7 +9,6 @@ on: env: CI_GRADLE_ARG_PROPERTIES: > -Porg.gradle.jvmargs=-Xmx4g - -Porg.gradle.parallel=false jobs: check: From fe793798fafa174323c4cd8b8461651abb056e1d Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:06:54 +0100 Subject: [PATCH 073/349] Ignore E2eeSanityTests. They fail infrequently, but in a way that takes the entire test framework down, so ignore them for now and open an issue to fix. --- .../org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 38597269cb..5e740a79ee 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -23,6 +23,7 @@ import org.amshove.kluent.fail import org.amshove.kluent.internal.assertEquals import org.junit.Assert import org.junit.FixMethodOrder +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -67,6 +68,7 @@ import java.util.concurrent.CountDownLatch @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) @LargeTest +@Ignore("This test fails with an unhandled exception thrown from a coroutine which terminates the entire test run.") class E2eeSanityTests : InstrumentedTest { @get:Rule val rule = RetryTestRule(3) From a4fa65b4fdf79e7baf38ab8f515c7f17f7eeec3c Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:37:41 +0100 Subject: [PATCH 074/349] Fix linting --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index 80ccf578e5..39f49a9ccc 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,7 +40,7 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() - if(i > 0) { + if (i > 0) { println("Retried test $i times") } return From 13175212a0835e606afe81141423920fda52b0bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 09:55:29 +0000 Subject: [PATCH 075/349] Bump constraintlayout from 2.1.3 to 2.1.4 Bumps [constraintlayout](https://github.com/androidx/constraintlayout) from 2.1.3 to 2.1.4. - [Release notes](https://github.com/androidx/constraintlayout/releases) - [Commits](https://github.com/androidx/constraintlayout/commits) --- updated-dependencies: - dependency-name: androidx.constraintlayout:constraintlayout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 10f9539e5a..47dc8ddc03 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -50,7 +50,7 @@ ext.libs = [ 'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1", 'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3", 'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1", - 'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.3", + '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", From 2081e2c45b859e2e0fc3f66838d4f8ab154a3439 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Fri, 20 May 2022 13:32:55 +0300 Subject: [PATCH 076/349] Reduce log visibility to verbose --- .../android/sdk/internal/crypto/MXOlmDevice.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 87384b3fe2..a657d757fb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -788,13 +788,13 @@ internal class MXOlmDevice @Inject constructor( } val messageIndexKey = senderKey + "|" + sessionId + "|" + roomId + "|" + decryptResult.mIndex - Timber.tag(loggerTag.value).d("##########################################################") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() timeline: $timeline") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() senderKey: $senderKey") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() sessionId: $sessionId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() roomId: $roomId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() eventId: $eventId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") + Timber.tag(loggerTag.value).v("##########################################################") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() timeline: $timeline") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() senderKey: $senderKey") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() sessionId: $sessionId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() roomId: $roomId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() eventId: $eventId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") if (timeline?.isNotBlank() == true) { val replayAttackMap = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableMapOf() } From 7bc880e6bf88abfcd38f51d8d02e4ad92f488fa0 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Fri, 20 May 2022 15:33:29 +0300 Subject: [PATCH 077/349] Improve documentation --- .../java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index a657d757fb..841e41da73 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -756,6 +756,7 @@ internal class MXOlmDevice @Inject constructor( * @param body the base64-encoded body of the encrypted message. * @param roomId the room in which the message was received. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. + * @param eventId the eventId of the message that will be decrypted * @param sessionId the session identifier. * @param senderKey the base64-encoded curve25519 key of the sender. * @return the decrypting result. Nil if the sessionId is unknown. From 1bea28e27a99ea9cb7abff9496370e14f02d4ece Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Fri, 20 May 2022 16:03:39 +0300 Subject: [PATCH 078/349] fix documentation format --- .../matrix/android/sdk/internal/crypto/MXOlmDevice.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 37d9a9f567..1d25d82549 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -753,13 +753,13 @@ internal class MXOlmDevice @Inject constructor( /** * Decrypt a received message with an inbound group session. * - * @param body the base64-encoded body of the encrypted message. - * @param roomId the room in which the message was received. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. - * @param eventId the eventId of the message that will be decrypted + * @param body the base64-encoded body of the encrypted message. + * @param roomId the room in which the message was received. + * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. + * @param eventId the eventId of the message that will be decrypted * @param sessionId the session identifier. * @param senderKey the base64-encoded curve25519 key of the sender. - * @return the decrypting result. Nil if the sessionId is unknown. + * @return the decrypting result. Null if the sessionId is unknown. */ @Throws(MXCryptoError::class) suspend fun decryptGroupMessage(body: String, From 85f35929382ed9f29f709ca9ffe5b3510c4bb877 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Fri, 20 May 2022 17:03:15 +0300 Subject: [PATCH 079/349] PR remarks --- .../sdk/internal/crypto/replayattack/ReplayAttackTest.kt | 3 ++- .../sdk/internal/session/sync/handler/room/RoomSyncHandler.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt index 9932375ed2..09c340a14f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -55,7 +55,7 @@ class ReplayAttackTest : InstrumentedTest { // Alice will send a message val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) - Assert.assertTrue("Message should be sent", sentEvents.size == 1) + assertEquals(1, sentEvents.size) val fakeEventId = sentEvents[0].eventId + "_fake" val fakeEventWithTheSameIndex = @@ -96,6 +96,7 @@ class ReplayAttackTest : InstrumentedTest { // Alice will send a message val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) Assert.assertTrue("Message should be sent", sentEvents.size == 1) + assertEquals(sentEvents.size, 1) testHelper.runBlockingTest { // Lets assume we are from the main timelineId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index df03b24a89..53fc9dc6b9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -539,7 +539,7 @@ internal class RoomSyncHandler @Inject constructor( } private fun generateTimelineId(roomId: String): String { - return "${RoomSyncHandler::class.java.simpleName}$roomId" + return "RoomSyncHandler$roomId" } data class EphemeralResult( From 2d351aa60f809b1b75adc2150fa97e9f5a4e692d Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 20 May 2022 15:20:24 +0100 Subject: [PATCH 080/349] applying api changes --- .../java/im/vector/app/core/utils/Emoji.kt | 4 ++-- .../home/room/detail/TimelineFragment.kt | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/utils/Emoji.kt b/vector/src/main/java/im/vector/app/core/utils/Emoji.kt index d6a63dca10..3e82ecd5f2 100644 --- a/vector/src/main/java/im/vector/app/core/utils/Emoji.kt +++ b/vector/src/main/java/im/vector/app/core/utils/Emoji.kt @@ -16,7 +16,7 @@ package im.vector.app.core.utils -import com.vanniktech.emoji.EmojiUtils +import com.vanniktech.emoji.isOnlyEmojis /** * Test if a string contains emojis. @@ -28,7 +28,7 @@ import com.vanniktech.emoji.EmojiUtils */ fun containsOnlyEmojis(str: String?): Boolean { // Now rely on vanniktech library - return EmojiUtils.isOnlyEmojis(str) + return str.isOnlyEmojis() } /** diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2bb620623c..19d2038e3c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -706,31 +706,31 @@ class TimelineFragment @Inject constructor( } private fun createEmojiPopup(): EmojiPopup { - return EmojiPopup - .Builder - .fromRootView(views.rootConstraintLayout) - .setKeyboardAnimationStyle(R.style.emoji_fade_animation_style) - .setOnEmojiPopupShownListener { + return EmojiPopup( + rootView = views.rootConstraintLayout, + keyboardAnimationStyle = R.style.emoji_fade_animation_style, + onEmojiPopupShownListener = { views.composerLayout.views.composerEmojiButton.apply { contentDescription = getString(R.string.a11y_close_emoji_picker) setImageResource(R.drawable.ic_keyboard) } - } - .setOnEmojiPopupDismissListenerLifecycleAware { + }, + onEmojiPopupDismissListener = lifecycleAwareDismissAction { views.composerLayout.views.composerEmojiButton.apply { contentDescription = getString(R.string.a11y_open_emoji_picker) setImageResource(R.drawable.ic_insert_emoji) } - } - .build(views.composerLayout.views.composerEditText) + }, + editText = views.composerLayout.views.composerEditText + ) } /** * Ensure dismiss actions only trigger when the fragment is in the started state. * EmojiPopup by default dismisses onViewDetachedFromWindow, this can cause race conditions with onDestroyView. */ - private fun EmojiPopup.Builder.setOnEmojiPopupDismissListenerLifecycleAware(action: () -> Unit): EmojiPopup.Builder { - return setOnEmojiPopupDismissListener { + private fun lifecycleAwareDismissAction(action: () -> Unit): () -> Unit { + return { if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) { action() } From bad62be49752c1352d0d27a7fc89614cbaecfc03 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 17:00:07 +0200 Subject: [PATCH 081/349] Use Kdoc format, else it's not extracted to the documentation by dokka --- .../crypto/keysbackup/KeysBackupState.kt | 42 +++++++++++++------ .../crypto/model/RoomEncryptionTrustLevel.kt | 16 +++++-- .../crypto/verification/VerificationMethod.kt | 12 ++++-- .../sdk/api/session/room/send/SendState.kt | 31 ++++++++++---- .../threads/ThreadNotificationState.kt | 15 ++++--- 5 files changed, 85 insertions(+), 31 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt index a4cc133398..c4392ef9f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt @@ -51,33 +51,51 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup * */ enum class KeysBackupState { - // Need to check the current backup version on the homeserver + /** + * Need to check the current backup version on the homeserver + */ Unknown, - // Checking if backup is enabled on homeserver + /** + * Checking if backup is enabled on homeserver + */ CheckingBackUpOnHomeserver, - // Backup has been stopped because a new backup version has been detected on the homeserver + /** + * Backup has been stopped because a new backup version has been detected on the homeserver + */ WrongBackUpVersion, - // Backup from this device is not enabled + /** + * Backup from this device is not enabled + */ Disabled, - // There is a backup available on the homeserver but it is not trusted. - // It is not trusted because the signature is invalid or the device that created it is not verified - // Use [KeysBackup.getKeysBackupTrust()] to get trust details. - // Consequently, the backup from this device is not enabled. + /** + * There is a backup available on the homeserver but it is not trusted. + * It is not trusted because the signature is invalid or the device that created it is not verified + * Use [KeysBackup.getKeysBackupTrust()] to get trust details. + * Consequently, the backup from this device is not enabled. + */ NotTrusted, - // Backup is being enabled: the backup version is being created on the homeserver + /** + * Backup is being enabled: the backup version is being created on the homeserver + */ Enabling, - // Backup is enabled and ready to send backup to the homeserver + /** + * Backup is enabled and ready to send backup to the homeserver + */ ReadyToBackUp, - // e2e keys are going to be sent to the homeserver + /** + * e2e keys are going to be sent to the homeserver + */ WillBackUp, - // e2e keys are being sent to the homeserver + /** + * e2e keys are being sent to the homeserver + */ BackingUp } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt index 68c7496d58..d030988303 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt @@ -20,15 +20,23 @@ package org.matrix.android.sdk.api.session.crypto.model * RoomEncryptionTrustLevel represents the trust level in an encrypted room. */ enum class RoomEncryptionTrustLevel { - // No one in the room has been verified -> Black shield + /** + * No one in the room has been verified -> Black shield + */ Default, - // There are one or more device un-verified -> the app should display a red shield + /** + * There are one or more device un-verified -> the app should display a red shield + */ Warning, - // All devices in the room are verified -> the app should display a green shield + /** + * All devices in the room are verified -> the app should display a green shield + */ Trusted, - // e2e is active but with an unsupported algorithm + /** + * e2e is active but with an unsupported algorithm + */ E2EWithUnsupportedAlgorithm } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt index f2de2c4b47..b3758c364b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt @@ -20,12 +20,18 @@ package org.matrix.android.sdk.api.session.crypto.verification * Verification methods. */ enum class VerificationMethod { - // Use it when your application supports the SAS verification method + /** + * Use it when your application supports the SAS verification method + */ SAS, - // Use it if your application is able to display QR codes + /** + * Use it if your application is able to display QR codes + */ QR_CODE_SHOW, - // Use it if your application is able to scan QR codes + /** + * Use it if your application is able to scan QR codes + */ QR_CODE_SCAN } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt index 7c806bf35b..bb4a649a95 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt @@ -17,27 +17,44 @@ package org.matrix.android.sdk.api.session.room.send enum class SendState { + /** + * The state is unknown + */ UNKNOWN, - // the event has not been sent + /** + * The event has not been sent + */ UNSENT, - // the event is encrypting + /** + * The event is encrypting + */ ENCRYPTING, - // the event is currently sending + /** + * The event is currently sending + */ SENDING, - // the event has been sent + /** + * The event has been sent + */ SENT, - // the event has been received from server + /** + * The event has been received from server + */ SYNCED, - // The event failed to be sent + /** + * The event failed to be sent + */ UNDELIVERED, - // the event failed to be sent because some unknown devices have been found while encrypting it + /** + * The event failed to be sent because some unknown devices have been found while encrypting it + */ FAILED_UNKNOWN_DEVICES; internal companion object { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt index c110802d23..226e7cc12e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt @@ -20,14 +20,19 @@ package org.matrix.android.sdk.api.session.threads * This class defines the state of a thread notification. */ enum class ThreadNotificationState { - - // There are no new message + /** + * There are no new message + */ NO_NEW_MESSAGE, - // There is at least one new message + /** + * There is at least one new message + */ NEW_MESSAGE, - // The is at least one new message that should be highlighted - // ex. "Hello @aris.kotsomitopoulos" + /** + * The is at least one new message that should be highlighted + * ex. "Hello @aris.kotsomitopoulos" + */ NEW_HIGHLIGHTED_MESSAGE; } From 96c825e265fd2f183f954760a6ed8d00fca47bca Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 17:25:58 +0200 Subject: [PATCH 082/349] Create _userstories package and add the 2 first user stories --- matrix-sdk-android/docs/packages.md | 4 +++ .../sdk/_userstories/Us000InitMatrix.kt | 28 +++++++++++++++++ .../android/sdk/_userstories/Us100SignIn.kt | 31 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt diff --git a/matrix-sdk-android/docs/packages.md b/matrix-sdk-android/docs/packages.md index ae7bee1b4e..98b0e0c034 100644 --- a/matrix-sdk-android/docs/packages.md +++ b/matrix-sdk-android/docs/packages.md @@ -1,3 +1,7 @@ +# Package org.matrix.android.sdk._userstories + +This package contains some user stories (**Us** prefix) of the SDK usage. You will find example of what it is possible to do with the SDK and the API which can be used to do it. + # Package org.matrix.android.sdk.api This is the root package of the API exposed by this SDK. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt new file mode 100644 index 0000000000..823a9522cf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Init a Matrix object + * + * ### Required APIs: + * - [org.matrix.android.sdk.api.Matrix] constructor + */ +object Us000InitMatrix diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt new file mode 100644 index 0000000000..5344e19ae4 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Sign in to an existing account + * + * #### Required APIs: + * - [org.matrix.android.sdk.api.Matrix.authenticationService] + * - [org.matrix.android.sdk.api.auth.AuthenticationService.getLoginFlow] + * - [org.matrix.android.sdk.api.auth.AuthenticationService.getLoginWizard] + * - [org.matrix.android.sdk.api.auth.login.LoginWizard.login] + */ +object Us100SignIn From cfd645661435619ad1dc542e32eb3ce9e6de55ef Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 17:51:08 +0200 Subject: [PATCH 083/349] Add other user stories (with TODO) --- .../sdk/_userstories/Us150VerifySession.kt | 28 +++++++++++++++++++ .../android/sdk/_userstories/Us190SignOut.kt | 28 +++++++++++++++++++ .../android/sdk/_userstories/Us200RoomList.kt | 28 +++++++++++++++++++ .../sdk/_userstories/Us300RoomTimeline.kt | 28 +++++++++++++++++++ .../Us350RoomTimelineFromPermalink.kt | 28 +++++++++++++++++++ .../sdk/_userstories/Us400RoomSendContent.kt | 28 +++++++++++++++++++ .../sdk/_userstories/Us500Notification.kt | 28 +++++++++++++++++++ .../_userstories/Us600SyncWithTheServer.kt | 28 +++++++++++++++++++ 8 files changed, 224 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt new file mode 100644 index 0000000000..59eb056cb0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Verify a Session after a Sign in + * + * #### Required APIs: + * - TODO + */ +object Us150VerifySession diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt new file mode 100644 index 0000000000..c9504e4a5e --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Sign out + * + * #### Required APIs: + * - TODO + */ +object Us190SignOut diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt new file mode 100644 index 0000000000..fa71b8cedf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Get the Room list + * + * #### Required APIs: + * - TODO + */ +object Us200RoomList diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt new file mode 100644 index 0000000000..ce899f53f8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Display a Room timeline, and navigate backward and forward + * + * #### Required APIs: + * - TODO + */ +object Us300RoomTimeline diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt new file mode 100644 index 0000000000..6684d2b8f3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Display a Room timeline at a specific point + * + * #### Required APIs: + * - TODO + */ +object Us350RoomTimelineFromPermalink diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt new file mode 100644 index 0000000000..fcff950228 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Send content to a room, including monitoring the sending state + * + * #### Required APIs: + * - TODO + */ +object Us400RoomSendContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt new file mode 100644 index 0000000000..a58f09a62c --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Get notified when new Events are received + * + * #### Required APIs: + * - TODO + */ +object Us500Notification diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt new file mode 100644 index 0000000000..52973259fd --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package org.matrix.android.sdk._userstories + +/** + * ### Title + * Manage the sync with the server + * + * #### Required APIs: + * - TODO + */ +object Us600SyncWithTheServer From e6c8ffd1b8330827a97b0c5214b9aa1a40ac804e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 18:07:31 +0200 Subject: [PATCH 084/349] Change `val` to `fun` on the SDK interfaces. Dokka will generate a better documentation (`Functions` and `Properties` are 2 distinct tab), and for Service it's better to have only `fun` --- .../sdk/api/auth/AuthenticationService.kt | 2 +- .../auth/registration/RegistrationWizard.kt | 8 ++++---- .../auth/DefaultAuthenticationService.kt | 3 +-- .../registration/DefaultRegistrationWizard.kt | 20 +++++++++---------- .../app/features/login/LoginViewModel.kt | 6 +++--- .../app/features/login2/LoginViewModel2.kt | 6 +++--- .../onboarding/OnboardingViewModel.kt | 6 +++--- 7 files changed, 24 insertions(+), 27 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt index 5a19df90c4..629d947bb3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt @@ -66,7 +66,7 @@ interface AuthenticationService { /** * True when login and password has been sent with success to the homeserver. */ - val isRegistrationStarted: Boolean + fun isRegistrationStarted(): Boolean /** * Cancel pending login or pending registration. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt index 0cda64499f..6100ae2a80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt @@ -109,14 +109,14 @@ interface RegistrationWizard { suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult /** - * This is the current ThreePid, waiting for validation. The SDK will store it in database, so it can be + * Returns the current ThreePid, waiting for validation. The SDK will store it in database, so it can be * restored even if the app has been killed during the registration */ - val currentThreePid: String? + fun currentThreePid(): String? /** - * True when login and password have been sent with success to the homeserver, i.e. [createAccount] has been + * Return true when login and password have been sent with success to the homeserver, i.e. [createAccount] has been * called successfully. */ - val isRegistrationStarted: Boolean + fun isRegistrationStarted(): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 02dfce04b5..fe78ccc75a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -323,8 +323,7 @@ internal class DefaultAuthenticationService @Inject constructor( } } - override val isRegistrationStarted: Boolean - get() = currentRegistrationWizard?.isRegistrationStarted == true + override fun isRegistrationStarted() = currentRegistrationWizard?.isRegistrationStarted() == true override fun getLoginWizard(): LoginWizard { return currentLoginWizard diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt index 8f00f3440c..03f54705fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt @@ -49,20 +49,18 @@ internal class DefaultRegistrationWizard( private val validateCodeTask: ValidateCodeTask = DefaultValidateCodeTask(authAPI) private val registerCustomTask: RegisterCustomTask = DefaultRegisterCustomTask(authAPI) - override val currentThreePid: String? - get() { - return when (val threePid = pendingSessionData.currentThreePidData?.threePid) { - is RegisterThreePid.Email -> threePid.email - is RegisterThreePid.Msisdn -> { - // Take formatted msisdn if provided by the server - pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn - } - null -> null + override fun currentThreePid(): String? { + return when (val threePid = pendingSessionData.currentThreePidData?.threePid) { + is RegisterThreePid.Email -> threePid.email + is RegisterThreePid.Msisdn -> { + // Take formatted msisdn if provided by the server + pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn } + null -> null } + } - override val isRegistrationStarted: Boolean - get() = pendingSessionData.isRegistrationStarted + override fun isRegistrationStarted() = pendingSessionData.isRegistrationStarted override suspend fun getRegistrationFlow(): RegistrationResult { val params = RegistrationParams() diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index 1b08d2a86f..ed9ec7b3b9 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -91,11 +91,11 @@ class LoginViewModel @AssistedInject constructor( private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() val currentThreePid: String? - get() = registrationWizard?.currentThreePid + get() = registrationWizard?.currentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean - get() = authenticationService.isRegistrationStarted + get() = authenticationService.isRegistrationStarted() private val registrationWizard: RegistrationWizard? get() = authenticationService.getRegistrationWizard() @@ -455,7 +455,7 @@ class LoginViewModel @AssistedInject constructor( // If there is a pending email validation continue on this step try { - if (registrationWizard?.isRegistrationStarted == true) { + if (registrationWizard?.isRegistrationStarted() == true) { currentThreePid?.let { handle(LoginAction.PostViewEvent(LoginViewEvents.OnSendEmailSuccess(it))) } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt index 6b9d255937..1117c32d39 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt @@ -92,11 +92,11 @@ class LoginViewModel2 @AssistedInject constructor( private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() val currentThreePid: String? - get() = registrationWizard?.currentThreePid + get() = registrationWizard?.currentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean - get() = authenticationService.isRegistrationStarted + get() = authenticationService.isRegistrationStarted() private val registrationWizard: RegistrationWizard? get() = authenticationService.getRegistrationWizard() @@ -420,7 +420,7 @@ class LoginViewModel2 @AssistedInject constructor( // If there is a pending email validation continue on this step try { - if (registrationWizard?.isRegistrationStarted == true) { + if (registrationWizard?.isRegistrationStarted() == true) { currentThreePid?.let { handle(LoginAction2.PostViewEvent(LoginViewEvents2.OnSendEmailSuccess(it))) } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 03526b47a5..b247086dbf 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -114,11 +114,11 @@ class OnboardingViewModel @AssistedInject constructor( get() = authenticationService.getRegistrationWizard() val currentThreePid: String? - get() = registrationWizard.currentThreePid + get() = registrationWizard.currentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean - get() = authenticationService.isRegistrationStarted + get() = authenticationService.isRegistrationStarted() private val loginWizard: LoginWizard? get() = authenticationService.getLoginWizard() @@ -396,7 +396,7 @@ class OnboardingViewModel @AssistedInject constructor( // If there is a pending email validation continue on this step try { - if (registrationWizard.isRegistrationStarted) { + if (registrationWizard.isRegistrationStarted()) { currentThreePid?.let { handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(it))) } From 768df330b522d1d7bb2abbb0b27e9636031b526c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 18:08:28 +0200 Subject: [PATCH 085/349] Rename `currentThreePid` to `getCurrentThreePid` --- .../android/sdk/api/auth/registration/RegistrationWizard.kt | 2 +- .../sdk/internal/auth/registration/DefaultRegistrationWizard.kt | 2 +- .../main/java/im/vector/app/features/login/LoginViewModel.kt | 2 +- .../main/java/im/vector/app/features/login2/LoginViewModel2.kt | 2 +- .../im/vector/app/features/onboarding/OnboardingViewModel.kt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt index 6100ae2a80..14d26bf2b3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationWizard.kt @@ -112,7 +112,7 @@ interface RegistrationWizard { * Returns the current ThreePid, waiting for validation. The SDK will store it in database, so it can be * restored even if the app has been killed during the registration */ - fun currentThreePid(): String? + fun getCurrentThreePid(): String? /** * Return true when login and password have been sent with success to the homeserver, i.e. [createAccount] has been diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt index 03f54705fc..345f4097db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt @@ -49,7 +49,7 @@ internal class DefaultRegistrationWizard( private val validateCodeTask: ValidateCodeTask = DefaultValidateCodeTask(authAPI) private val registerCustomTask: RegisterCustomTask = DefaultRegisterCustomTask(authAPI) - override fun currentThreePid(): String? { + override fun getCurrentThreePid(): String? { return when (val threePid = pendingSessionData.currentThreePidData?.threePid) { is RegisterThreePid.Email -> threePid.email is RegisterThreePid.Msisdn -> { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index ed9ec7b3b9..cacbd0e282 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -91,7 +91,7 @@ class LoginViewModel @AssistedInject constructor( private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() val currentThreePid: String? - get() = registrationWizard?.currentThreePid() + get() = registrationWizard?.getCurrentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt index 1117c32d39..06388a04a0 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt @@ -92,7 +92,7 @@ class LoginViewModel2 @AssistedInject constructor( private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() val currentThreePid: String? - get() = registrationWizard?.currentThreePid() + get() = registrationWizard?.getCurrentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index b247086dbf..f795b39c51 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -114,7 +114,7 @@ class OnboardingViewModel @AssistedInject constructor( get() = authenticationService.getRegistrationWizard() val currentThreePid: String? - get() = registrationWizard.currentThreePid() + get() = registrationWizard.getCurrentThreePid() // True when login and password has been sent with success to the homeserver val isRegistrationStarted: Boolean From d3d17ebbcb51ff170125b5cca1f82b0b206c2806 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 18:17:23 +0200 Subject: [PATCH 086/349] Extract HttpPusher to its own file --- .../sdk/api/session/pushers/HttpPusher.kt | 73 +++++++++++++++++++ .../sdk/api/session/pushers/PushersService.kt | 57 --------------- .../session/pushers/DefaultPushersService.kt | 7 +- .../vector/app/core/pushers/PushersManager.kt | 4 +- 4 files changed, 79 insertions(+), 62 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/HttpPusher.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/HttpPusher.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/HttpPusher.kt new file mode 100644 index 0000000000..1ae23e2b70 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/HttpPusher.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.pushers + +data class HttpPusher( + /** + * This is a unique identifier for this pusher. The value you should use for + * this is the routing or destination address information for the notification, + * for example, the APNS token for APNS or the Registration ID for GCM. If your + * notification client has no such concept, use any unique identifier. Max length, 512 chars. + */ + val pushkey: String, + + /** + * The application id + * This is a reverse-DNS style identifier for the application. It is recommended + * that this end with the platform, such that different platform versions get + * different app identifiers. Max length, 64 chars. + */ + val appId: String, + + /** + * This string determines which set of device specific rules this pusher executes. + */ + val profileTag: String, + + /** + * The preferred language for receiving notifications (e.g. "en" or "en-US"). + */ + val lang: String, + + /** + * A human readable string that will allow the user to identify what application owns this pusher. + */ + val appDisplayName: String, + + /** + * A human readable string that will allow the user to identify what device owns this pusher. + */ + val deviceDisplayName: String, + + /** + * The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify. + */ + val url: String, + + /** + * If true, the homeserver should add another pusher with the given pushkey and App ID in addition + * to any others with different user IDs. Otherwise, the homeserver must remove any other pushers + * with the same App ID and pushkey for different users. + */ + val append: Boolean, + + /** + * true to limit the push content to only id and not message content + * Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour + */ + val withEventIdOnly: Boolean +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index 5cb7857021..396f13ce46 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -107,61 +107,4 @@ interface PushersService { * Get the current pushers. */ fun getPushers(): List - - data class HttpPusher( - - /** - * This is a unique identifier for this pusher. The value you should use for - * this is the routing or destination address information for the notification, - * for example, the APNS token for APNS or the Registration ID for GCM. If your - * notification client has no such concept, use any unique identifier. Max length, 512 chars. - */ - val pushkey: String, - - /** - * The application id - * This is a reverse-DNS style identifier for the application. It is recommended - * that this end with the platform, such that different platform versions get - * different app identifiers. Max length, 64 chars. - */ - val appId: String, - - /** - * This string determines which set of device specific rules this pusher executes. - */ - val profileTag: String, - - /** - * The preferred language for receiving notifications (e.g. "en" or "en-US"). - */ - val lang: String, - - /** - * A human readable string that will allow the user to identify what application owns this pusher. - */ - val appDisplayName: String, - - /** - * A human readable string that will allow the user to identify what device owns this pusher. - */ - val deviceDisplayName: String, - - /** - * The URL to use to send notifications to. MUST be an HTTPS URL with a path of /_matrix/push/v1/notify. - */ - val url: String, - - /** - * If true, the homeserver should add another pusher with the given pushkey and App ID in addition - * to any others with different user IDs. Otherwise, the homeserver must remove any other pushers - * with the same App ID and pushkey for different users. - */ - val append: Boolean, - - /** - * true to limit the push content to only id and not message content - * Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#homeserver-behaviour - */ - val withEventIdOnly: Boolean - ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt index 13b990a9ff..9437550d7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.pushers import androidx.lifecycle.LiveData import androidx.work.BackoffPolicy import com.zhuinden.monarchy.Monarchy +import org.matrix.android.sdk.api.session.pushers.HttpPusher import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.pushers.PushersService import org.matrix.android.sdk.internal.database.mapper.asDomain @@ -58,15 +59,15 @@ internal class DefaultPushersService @Inject constructor( .executeBy(taskExecutor) } - override fun enqueueAddHttpPusher(httpPusher: PushersService.HttpPusher): UUID { + override fun enqueueAddHttpPusher(httpPusher: HttpPusher): UUID { return enqueueAddPusher(httpPusher.toJsonPusher()) } - override suspend fun addHttpPusher(httpPusher: PushersService.HttpPusher) { + override suspend fun addHttpPusher(httpPusher: HttpPusher) { addPusherTask.execute(AddPusherTask.Params(httpPusher.toJsonPusher())) } - private fun PushersService.HttpPusher.toJsonPusher() = JsonPusher( + private fun HttpPusher.toJsonPusher() = JsonPusher( pushKey = pushkey, kind = "http", appId = appId, diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt index b1bb4c7d88..c89dc7a73c 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt @@ -21,7 +21,7 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.resources.AppNameProvider import im.vector.app.core.resources.LocaleProvider import im.vector.app.core.resources.StringProvider -import org.matrix.android.sdk.api.session.pushers.PushersService +import org.matrix.android.sdk.api.session.pushers.HttpPusher import java.util.UUID import javax.inject.Inject import kotlin.math.abs @@ -55,7 +55,7 @@ class PushersManager @Inject constructor( currentSession.pushersService().addHttpPusher(createHttpPusher(pushKey)) } - private fun createHttpPusher(pushKey: String) = PushersService.HttpPusher( + private fun createHttpPusher(pushKey: String) = HttpPusher( pushKey, stringProvider.getString(R.string.pusher_app_id), profileTag = DEFAULT_PUSHER_FILE_TAG + "_" + abs(activeSessionHolder.getActiveSession().myUserId.hashCode()), From 1ab4ae9eac2b91e654b24370ad4cae95ca758bac Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 18:19:27 +0200 Subject: [PATCH 087/349] Extract KeyRef to its own file --- .../sdk/internal/crypto/ssss/QuadSTests.kt | 10 ++++----- .../sdk/api/session/securestorage/KeyRef.kt | 22 +++++++++++++++++++ .../SharedSecretStorageService.kt | 5 ----- .../DefaultSharedSecretStorageService.kt | 3 ++- .../recover/BackupToQuadSMigrationTask.kt | 4 ++-- .../recover/BootstrapCrossSigningTask.kt | 12 +++++----- .../fakes/FakeSharedSecretStorageService.kt | 3 ++- 7 files changed, 39 insertions(+), 20 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/KeyRef.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt index c758050fc9..dbe6f076d6 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt @@ -31,11 +31,11 @@ import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.KeySigner import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError -import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toBase64NoPadding @@ -123,7 +123,7 @@ class QuadSTests : InstrumentedTest { aliceSession.sharedSecretStorageService().storeSecret( "secret.of.life", clearSecret, - listOf(SharedSecretStorageService.KeyRef(null, keySpec)) // default key + listOf(KeyRef(null, keySpec)) // default key ) } @@ -191,8 +191,8 @@ class QuadSTests : InstrumentedTest { "my.secret", mySecretText.toByteArray().toBase64NoPadding(), listOf( - SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)), - SharedSecretStorageService.KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)) + KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)), + KeyRef(keyId2, RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)) ) ) } @@ -241,7 +241,7 @@ class QuadSTests : InstrumentedTest { aliceSession.sharedSecretStorageService().storeSecret( "my.secret", mySecretText.toByteArray().toBase64NoPadding(), - listOf(SharedSecretStorageService.KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey))) + listOf(KeyRef(keyId1, RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey))) ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/KeyRef.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/KeyRef.kt new file mode 100644 index 0000000000..5a1bf67fdd --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/KeyRef.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.securestorage + +data class KeyRef( + val keyId: String?, + val keySpec: SsssKeySpec? +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt index e3a9860523..929463563f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt @@ -132,9 +132,4 @@ interface SharedSecretStorageService { fun checkShouldBeAbleToAccessSecrets(secretNames: List, keyId: String?): IntegrityResult suspend fun requestSecret(name: String, myOtherDeviceId: String) - - data class KeyRef( - val keyId: String?, - val keySpec: SsssKeySpec? - ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt index 1ded9c6c7e..0daaec11a1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt @@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent import org.matrix.android.sdk.api.session.securestorage.IntegrityResult import org.matrix.android.sdk.api.session.securestorage.KeyInfo import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.KeySigner import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent @@ -157,7 +158,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor( return getKey(keyId) } - override suspend fun storeSecret(name: String, secretBase64: String, keys: List) { + override suspend fun storeSecret(name: String, secretBase64: String, keys: List) { withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) { val encryptedContents = HashMap() keys.forEach { diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt index e620500d70..5d866c7220 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt @@ -26,8 +26,8 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec -import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.toBase64NoPadding @@ -142,7 +142,7 @@ class BackupToQuadSMigrationTask @Inject constructor( quadS.storeSecret( KEYBACKUP_SECRET_SSSS_NAME, curveKey.toBase64NoPadding(), - listOf(SharedSecretStorageService.KeyRef(info.keyId, info.keySpec)) + listOf(KeyRef(info.keyId, info.keySpec)) ) // save for gossiping diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt index c26aec45dd..6926c0b30b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreation import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner -import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.api.util.awaitCallback @@ -183,7 +183,7 @@ class BootstrapCrossSigningTask @Inject constructor( ssssService.storeSecret( MASTER_KEY_SSSS_NAME, mskPrivateKey, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) params.progressListener?.onProgress( WaitingViewData( @@ -195,7 +195,7 @@ class BootstrapCrossSigningTask @Inject constructor( ssssService.storeSecret( USER_SIGNING_KEY_SSSS_NAME, uskPrivateKey, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) params.progressListener?.onProgress( WaitingViewData( @@ -206,7 +206,7 @@ class BootstrapCrossSigningTask @Inject constructor( ssssService.storeSecret( SELF_SIGNING_KEY_SSSS_NAME, sskPrivateKey, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) } catch (failure: Failure) { Timber.e("## BootstrapCrossSigningTask: Creating 4S - Failed to store keys <${failure.localizedMessage}>") @@ -258,7 +258,7 @@ class BootstrapCrossSigningTask @Inject constructor( ssssService.storeSecret( KEYBACKUP_SECRET_SSSS_NAME, secret, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) } } else { @@ -275,7 +275,7 @@ class BootstrapCrossSigningTask @Inject constructor( ssssService.storeSecret( KEYBACKUP_SECRET_SSSS_NAME, secret, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) } } else { diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSharedSecretStorageService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSharedSecretStorageService.kt index c79a0be542..e81bd8f90e 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSharedSecretStorageService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSharedSecretStorageService.kt @@ -19,6 +19,7 @@ package im.vector.app.test.fakes import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.securestorage.IntegrityResult import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.KeySigner import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService @@ -56,7 +57,7 @@ class FakeSharedSecretStorageService : SharedSecretStorageService { TODO("Not yet implemented") } - override suspend fun storeSecret(name: String, secretBase64: String, keys: List) { + override suspend fun storeSecret(name: String, secretBase64: String, keys: List) { TODO("Not yet implemented") } From ede784684f6be4ee8b2327c7b64667375b8e0046 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 18:58:41 +0200 Subject: [PATCH 088/349] Change in KeysBackupService: `isEnabled` and `isStucked` are now fun, and `state` has been renamed to `getState` and is now a fun. --- .../crypto/keysbackup/KeysBackupTest.kt | 66 +++++++++---------- .../crypto/keysbackup/KeysBackupTestHelper.kt | 6 +- .../crypto/keysbackup/KeysBackupService.kt | 9 ++- .../keysbackup/DefaultKeysBackupService.kt | 34 ++++------ .../im/vector/app/SecurityBootstrapTest.kt | 2 +- .../im/vector/app/core/extensions/Session.kt | 2 +- .../settings/KeysBackupSettingsViewModel.kt | 4 +- .../action/MessageActionsViewModel.kt | 4 +- .../signout/ServerBackupStatusViewModel.kt | 6 +- .../workers/signout/SignoutCheckViewModel.kt | 2 +- 10 files changed, 66 insertions(+), 69 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 9136272b1e..5c324852ee 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -113,7 +113,7 @@ class KeysBackupTest : InstrumentedTest { val stateObserver = StateObserver(keysBackup) - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) val megolmBackupCreationInfo = testHelper.doSync { keysBackup.prepareKeysBackupVersion(null, null, it) @@ -143,13 +143,13 @@ class KeysBackupTest : InstrumentedTest { val stateObserver = StateObserver(keysBackup) - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) val megolmBackupCreationInfo = testHelper.doSync { keysBackup.prepareKeysBackupVersion(null, null, it) } - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) // Create the version val version = testHelper.doSync { @@ -157,7 +157,7 @@ class KeysBackupTest : InstrumentedTest { } // Backup must be enable now - assertTrue(keysBackup.isEnabled) + assertTrue(keysBackup.isEnabled()) // Check that it's signed with MSK val versionResult = testHelper.doSync { @@ -441,8 +441,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) // - Trust the backup from the new device testHelper.doSync { @@ -458,7 +458,7 @@ class KeysBackupTest : InstrumentedTest { // - Backup must be enabled on the new device, on the same version assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version) - assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) + assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) // - Retrieve the last version from the server val keysVersionResult = testHelper.doSync { @@ -504,8 +504,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) // - Trust the backup from the new device with the recovery key testHelper.doSync { @@ -521,7 +521,7 @@ class KeysBackupTest : InstrumentedTest { // - Backup must be enabled on the new device, on the same version assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version) - assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) + assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) // - Retrieve the last version from the server val keysVersionResult = testHelper.doSync { @@ -565,8 +565,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) // - Try to trust the backup from the new device with a wrong recovery key val latch = CountDownLatch(1) @@ -579,8 +579,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must still see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) stateObserver.stopAndCheckStates(null) testData.cleanUp(testHelper) @@ -612,8 +612,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) // - Trust the backup from the new device with the password testHelper.doSync { @@ -629,7 +629,7 @@ class KeysBackupTest : InstrumentedTest { // - Backup must be enabled on the new device, on the same version assertEquals(testData.prepareKeysBackupDataResult.version, testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion?.version) - assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) + assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) // - Retrieve the last version from the server val keysVersionResult = testHelper.doSync { @@ -676,8 +676,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) // - Try to trust the backup from the new device with a wrong password val latch = CountDownLatch(1) @@ -690,8 +690,8 @@ class KeysBackupTest : InstrumentedTest { // - The new device must still see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) - assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) - assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) + assertFalse(testData.aliceSession2.cryptoService().keysBackupService().isEnabled()) + assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().getState()) stateObserver.stopAndCheckStates(null) testData.cleanUp(testHelper) @@ -969,7 +969,7 @@ class KeysBackupTest : InstrumentedTest { val stateObserver = StateObserver(keysBackup) - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) // Wait for keys backup to be finished val latch0 = CountDownLatch(1) @@ -993,7 +993,7 @@ class KeysBackupTest : InstrumentedTest { // - Make alice back up her keys to her homeserver keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) - assertTrue(keysBackup.isEnabled) + assertTrue(keysBackup.isEnabled()) testHelper.await(latch0) @@ -1012,8 +1012,8 @@ class KeysBackupTest : InstrumentedTest { testHelper.await(latch2) // -> That must fail and her backup state must be WrongBackUpVersion - assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.state) - assertFalse(keysBackup.isEnabled) + assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.getState()) + assertFalse(keysBackup.isEnabled()) stateObserver.stopAndCheckStates(null) cryptoTestData.cleanUp(testHelper) @@ -1069,7 +1069,7 @@ class KeysBackupTest : InstrumentedTest { // - Try to backup all in aliceSession2, it must fail val keysBackup2 = aliceSession2.cryptoService().keysBackupService() - assertFalse("Backup should not be enabled", keysBackup2.isEnabled) + assertFalse("Backup should not be enabled", keysBackup2.isEnabled()) val stateObserver2 = StateObserver(keysBackup2) @@ -1088,8 +1088,8 @@ class KeysBackupTest : InstrumentedTest { assertFalse(isSuccessful) // Backup state must be NotTrusted - assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.state) - assertFalse("Backup should not be enabled", keysBackup2.isEnabled) + assertEquals("Backup state must be NotTrusted", KeysBackupState.NotTrusted, keysBackup2.getState()) + assertFalse("Backup should not be enabled", keysBackup2.isEnabled()) // - Validate the old device from the new one aliceSession2.cryptoService().setDeviceVerification( @@ -1103,7 +1103,7 @@ class KeysBackupTest : InstrumentedTest { keysBackup2.addListener(object : KeysBackupStateListener { override fun onStateChange(newState: KeysBackupState) { // Check the backup completes - if (keysBackup2.state == KeysBackupState.ReadyToBackUp) { + if (keysBackup2.getState() == KeysBackupState.ReadyToBackUp) { // Remove itself from the list of listeners keysBackup2.removeListener(this) @@ -1121,7 +1121,7 @@ class KeysBackupTest : InstrumentedTest { } // -> It must success - assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled) + assertTrue(aliceSession2.cryptoService().keysBackupService().isEnabled()) stateObserver.stopAndCheckStates(null) stateObserver2.stopAndCheckStates(null) @@ -1146,17 +1146,17 @@ class KeysBackupTest : InstrumentedTest { val stateObserver = StateObserver(keysBackup) - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) val keyBackupCreationInfo = keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) - assertTrue(keysBackup.isEnabled) + assertTrue(keysBackup.isEnabled()) // Delete the backup testHelper.doSync { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) } // Backup is now disabled - assertFalse(keysBackup.isEnabled) + assertFalse(keysBackup.isEnabled()) stateObserver.stopAndCheckStates(null) cryptoTestData.cleanUp(testHelper) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt index 2220536e28..4eccdfad1f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt @@ -106,7 +106,7 @@ internal class KeysBackupTestHelper( Assert.assertNotNull(megolmBackupCreationInfo) - Assert.assertFalse("Key backup should not be enabled before creation", keysBackup.isEnabled) + Assert.assertFalse("Key backup should not be enabled before creation", keysBackup.isEnabled()) // Create the version val keysVersion = testHelper.doSync { @@ -116,7 +116,7 @@ internal class KeysBackupTestHelper( Assert.assertNotNull("Key backup version should not be null", keysVersion.version) // Backup must be enable now - Assert.assertTrue(keysBackup.isEnabled) + Assert.assertTrue(keysBackup.isEnabled()) stateObserver.stopAndCheckStates(null) return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version) @@ -128,7 +128,7 @@ internal class KeysBackupTestHelper( */ fun waitForKeysBackupToBeInState(session: Session, state: KeysBackupState) { // If already in the wanted state, return - if (session.cryptoService().keysBackupService().state == state) { + if (session.cryptoService().keysBackupService().getState() == state) { return } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 9029c7f8a3..b36797acf6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -204,10 +204,13 @@ interface KeysBackupService { callback: MatrixCallback) val keysBackupVersion: KeysVersionResult? + val currentBackupVersion: String? - val isEnabled: Boolean - val isStucked: Boolean - val state: KeysBackupState + get() = keysBackupVersion?.version + + fun isEnabled(): Boolean + fun isStucked(): Boolean + fun getState(): KeysBackupState // For gossiping fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 813adf7459..520f2be4d0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -137,17 +137,11 @@ internal class DefaultKeysBackupService @Inject constructor( private var keysBackupStateListener: KeysBackupStateListener? = null - override val isEnabled: Boolean - get() = keysBackupStateManager.isEnabled + override fun isEnabled(): Boolean = keysBackupStateManager.isEnabled - override val isStucked: Boolean - get() = keysBackupStateManager.isStucked + override fun isStucked(): Boolean = keysBackupStateManager.isStucked - override val state: KeysBackupState - get() = keysBackupStateManager.state - - override val currentBackupVersion: String? - get() = keysBackupVersion?.version + override fun getState(): KeysBackupState = keysBackupStateManager.state override fun addListener(listener: KeysBackupStateListener) { keysBackupStateManager.addListener(listener) @@ -291,7 +285,7 @@ internal class DefaultKeysBackupService @Inject constructor( this.callback = object : MatrixCallback { private fun eventuallyRestartBackup() { // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver - if (state == KeysBackupState.Unknown) { + if (getState() == KeysBackupState.Unknown) { checkAndStartKeysBackup() } } @@ -383,7 +377,7 @@ internal class DefaultKeysBackupService @Inject constructor( } // If backup is finished, notify the main listener - if (state === KeysBackupState.ReadyToBackUp) { + if (getState() === KeysBackupState.ReadyToBackUp) { backupAllGroupSessionsCallback?.onSuccess(Unit) resetBackupAllGroupSessionsListeners() } @@ -915,12 +909,12 @@ internal class DefaultKeysBackupService @Inject constructor( */ fun maybeBackupKeys() { when { - isStucked -> { + isStucked() -> { // If not already done, or in error case, check for a valid backup version on the homeserver. // If there is one, maybeBackupKeys will be called again. checkAndStartKeysBackup() } - state == KeysBackupState.ReadyToBackUp -> { + getState() == KeysBackupState.ReadyToBackUp -> { keysBackupStateManager.state = KeysBackupState.WillBackUp // Wait between 0 and 10 seconds, to avoid backup requests from @@ -933,8 +927,8 @@ internal class DefaultKeysBackupService @Inject constructor( uiHandler.post { backupKeys() } } } - else -> { - Timber.v("maybeBackupKeys: Skip it because state: $state") + else -> { + Timber.v("maybeBackupKeys: Skip it because state: ${getState()}") } } } @@ -1018,9 +1012,9 @@ internal class DefaultKeysBackupService @Inject constructor( } override fun checkAndStartKeysBackup() { - if (!isStucked) { + if (!isStucked()) { // Try to start or restart the backup only if it is in unknown or bad state - Timber.w("checkAndStartKeysBackup: invalid state: $state") + Timber.w("checkAndStartKeysBackup: invalid state: ${getState()}") return } @@ -1259,16 +1253,16 @@ internal class DefaultKeysBackupService @Inject constructor( Timber.v("backupKeys") // Sanity check, as this method can be called after a delay, the state may have change during the delay - if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) { + if (!isEnabled() || backupOlmPkEncryption == null || keysBackupVersion == null) { Timber.v("backupKeys: Invalid configuration") backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) resetBackupAllGroupSessionsListeners() return } - if (state === KeysBackupState.BackingUp) { + if (getState() === KeysBackupState.BackingUp) { // Do nothing if we are already backing up - Timber.v("backupKeys: Invalid state: $state") + Timber.v("backupKeys: Invalid state: ${getState()}") return } diff --git a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt index 21fd226317..eaf39310a8 100644 --- a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt +++ b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt @@ -165,7 +165,7 @@ class SecurityBootstrapTest : VerificationTestBase() { assert(uiSession.cryptoService().crossSigningService().isCrossSigningInitialized()) assert(uiSession.cryptoService().crossSigningService().canCrossSign()) assert(uiSession.cryptoService().crossSigningService().allPrivateKeysKnown()) - assert(uiSession.cryptoService().keysBackupService().isEnabled) + assert(uiSession.cryptoService().keysBackupService().isEnabled()) assert(uiSession.cryptoService().keysBackupService().currentBackupVersion != null) assert(uiSession.sharedSecretStorageService().isRecoverySetup()) assert(uiSession.sharedSecretStorageService().isMegolmKeyInBackup()) diff --git a/vector/src/main/java/im/vector/app/core/extensions/Session.kt b/vector/src/main/java/im/vector/app/core/extensions/Session.kt index 1884909906..2a2198d96b 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Session.kt @@ -66,7 +66,7 @@ fun Session.startSyncing(context: Context) { */ fun Session.hasUnsavedKeys(): Boolean { return cryptoService().inboundGroupSessionsCount(false) > 0 && - cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp + cryptoService().keysBackupService().getState() != KeysBackupState.ReadyToBackUp } fun Session.cannotLogoutSafely(): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index b47b84af71..dea481dbad 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -60,7 +60,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS init { setState { this.copy( - keysBackupState = keysBackupService.state, + keysBackupState = keysBackupService.getState(), keysBackupVersion = keysBackupService.keysBackupVersion ) } @@ -206,7 +206,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS } fun canExit(): Boolean { - val currentBackupState = keysBackupService.state + val currentBackupState = keysBackupService.getState() return currentBackupState == KeysBackupState.Unknown || currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 4bc513284b..79a6dd27ff 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -401,8 +401,8 @@ class MessageActionsViewModel @AssistedInject constructor( if (vectorPreferences.developerMode()) { if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) { val keysBackupService = session.cryptoService().keysBackupService() - if (keysBackupService.state == KeysBackupState.NotTrusted || - (keysBackupService.state == KeysBackupState.ReadyToBackUp && + if (keysBackupService.getState() == KeysBackupState.NotTrusted || + (keysBackupService.getState() == KeysBackupState.ReadyToBackUp && keysBackupService.canRestoreKeys()) ) { add(EventSharedAction.UseKeyBackup) diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index 8c24b2893a..6a38de44c6 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -81,7 +81,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS init { session.cryptoService().keysBackupService().addListener(this) - keysBackupState.value = session.cryptoService().keysBackupService().state + keysBackupState.value = session.cryptoService().keysBackupService().getState() val liveUserAccountData = session.flow().liveUserAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME)) val liveCrossSigningInfo = session.flow().liveCrossSigningInfo(session.myUserId) val liveCrossSigningPrivateKeys = session.flow().liveCrossSigningPrivateKeys() @@ -116,7 +116,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS } viewModelScope.launch { - keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().getState()) } } @@ -148,7 +148,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS override fun onStateChange(newState: KeysBackupState) { viewModelScope.launch { - keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().getState()) } keysBackupState.value = newState } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt index 79df62d7fb..49d1192b2b 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt @@ -76,7 +76,7 @@ class SignoutCheckViewModel @AssistedInject constructor( val quad4SIsSetup = session.sharedSecretStorageService().isRecoverySetup() val allKeysKnown = session.cryptoService().crossSigningService().allPrivateKeysKnown() - val backupState = session.cryptoService().keysBackupService().state + val backupState = session.cryptoService().keysBackupService().getState() setState { copy( userId = session.myUserId, From 853c0a25bfafb99553eef232e3ce39035e8c5cdf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 19:00:03 +0200 Subject: [PATCH 089/349] Method `onSecretKeyGossip` doe snot have to be in the public interface --- .../sdk/api/session/crypto/keysbackup/KeysBackupService.kt | 2 -- .../sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index b36797acf6..824ed1b992 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -168,8 +168,6 @@ interface KeysBackupService { password: String, callback: MatrixCallback) - fun onSecretKeyGossip(secret: String) - /** * Restore a backup with a recovery key from a given backup version stored on the homeserver. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 520f2be4d0..fe63529547 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -622,7 +622,7 @@ internal class DefaultKeysBackupService @Inject constructor( } } - override fun onSecretKeyGossip(secret: String) { + fun onSecretKeyGossip(secret: String) { Timber.i("## CrossSigning - onSecretKeyGossip") cryptoCoroutineScope.launch(coroutineDispatchers.io) { From 740acda60bc4ac58be4b1f85c08e6c294f458366 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 20:53:02 +0200 Subject: [PATCH 090/349] Please ktlint. Ok, the user story will appear at the end of the doc. --- .../sdk/{_userstories => userstories}/Us000InitMatrix.kt | 2 +- .../android/sdk/{_userstories => userstories}/Us100SignIn.kt | 2 +- .../sdk/{_userstories => userstories}/Us150VerifySession.kt | 2 +- .../android/sdk/{_userstories => userstories}/Us190SignOut.kt | 2 +- .../android/sdk/{_userstories => userstories}/Us200RoomList.kt | 2 +- .../sdk/{_userstories => userstories}/Us300RoomTimeline.kt | 2 +- .../Us350RoomTimelineFromPermalink.kt | 2 +- .../sdk/{_userstories => userstories}/Us400RoomSendContent.kt | 2 +- .../sdk/{_userstories => userstories}/Us500Notification.kt | 2 +- .../sdk/{_userstories => userstories}/Us600SyncWithTheServer.kt | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us000InitMatrix.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us100SignIn.kt (95%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us150VerifySession.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us190SignOut.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us200RoomList.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us300RoomTimeline.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us350RoomTimelineFromPermalink.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us400RoomSendContent.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us500Notification.kt (94%) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/{_userstories => userstories}/Us600SyncWithTheServer.kt (94%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt index 823a9522cf..1eb926c54a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us000InitMatrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt index 5344e19ae4..fdd78737f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us100SignIn.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt index 59eb056cb0..6ccee2e783 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us150VerifySession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt index c9504e4a5e..fb50449148 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us190SignOut.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt index fa71b8cedf..acc73aa340 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us200RoomList.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt index ce899f53f8..23a06ba27a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us300RoomTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt index 6684d2b8f3..6d0ae32cca 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us350RoomTimelineFromPermalink.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt index fcff950228..8938f0703d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us400RoomSendContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt index a58f09a62c..5d08ac2366 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us500Notification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt index 52973259fd..f6532ae9d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/_userstories/Us600SyncWithTheServer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt @@ -16,7 +16,7 @@ @file:Suppress("unused") -package org.matrix.android.sdk._userstories +package org.matrix.android.sdk.userstories /** * ### Title From 6e3979a32d9c9a6d713ef47602355233eaf8da32 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 23:52:53 +0200 Subject: [PATCH 091/349] Fix test compilation --- .../java/im/vector/app/test/fakes/FakeAuthenticationService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt index fedda18aeb..0456bbd474 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt @@ -33,7 +33,7 @@ class FakeAuthenticationService : AuthenticationService by mockk() { } fun givenRegistrationStarted(started: Boolean) { - every { isRegistrationStarted } returns started + every { isRegistrationStarted() } returns started } fun givenLoginFlow(config: HomeServerConnectionConfig, result: LoginFlowResult) { From d92875e3c2211eee2992f5468e42fe4f2b34ff98 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 May 2022 23:54:00 +0200 Subject: [PATCH 092/349] Improve documentation --- .../auth/registration/RegistrationResult.kt | 20 ++++++++++++- .../sdk/api/auth/registration/Stage.kt | 29 ++++++++++++++----- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt index 439b4beb41..f1639d2a09 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt @@ -18,13 +18,31 @@ package org.matrix.android.sdk.api.auth.registration import org.matrix.android.sdk.api.session.Session -// Either a session or an object containing data about registration stages +/** + * Either a session or an object containing data about registration stages + */ sealed class RegistrationResult { + /** + * The registration is successful, the [Session] is provided + */ data class Success(val session: Session) : RegistrationResult() + + /** + * The registration still miss some steps. See [FlowResult] to know the details + */ data class FlowResponse(val flowResult: FlowResult) : RegistrationResult() } +/** + * Information about the missing and completed [Stage] + */ data class FlowResult( + /** + * List of missing stages + */ val missingStages: List, + /** + * List of completed stages + */ val completedStages: List ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt index c21b667cf7..ce834b976d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt @@ -16,25 +16,40 @@ package org.matrix.android.sdk.api.auth.registration +/** + * Registration stages + */ sealed class Stage(open val mandatory: Boolean) { - // m.login.recaptcha + /** + * m.login.recaptcha stage + */ data class ReCaptcha(override val mandatory: Boolean, val publicKey: String) : Stage(mandatory) - // m.login.email.identity + /** + * m.login.email.identity stage + */ data class Email(override val mandatory: Boolean) : Stage(mandatory) - // m.login.msisdn + /** + * m.login.msisdn stage + */ data class Msisdn(override val mandatory: Boolean) : Stage(mandatory) - // m.login.dummy, can be mandatory if there is no other stages. In this case the account cannot be created by just sending a username - // and a password, the dummy stage has to be done + /** + * m.login.dummy, can be mandatory if there is no other stages. In this case the account cannot be created by just sending a username + * and a password, the dummy stage has to be done + */ data class Dummy(override val mandatory: Boolean) : Stage(mandatory) - // Undocumented yet: m.login.terms + /** + * Undocumented yet: m.login.terms stage + */ data class Terms(override val mandatory: Boolean, val policies: TermPolicies) : Stage(mandatory) - // For unknown stages + /** + * For unknown stages + */ data class Other(override val mandatory: Boolean, val type: String, val params: Map<*, *>?) : Stage(mandatory) } From dc1eba28475df0945e2afcc486627b5405bf2d91 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 May 2022 00:04:44 +0200 Subject: [PATCH 093/349] Improve documentation --- .../android/sdk/api/cache/CacheStrategy.kt | 14 +++++++---- .../matrix/android/sdk/api/failure/Failure.kt | 4 +++- .../verification/VerificationTxState.kt | 24 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt index 2880d851d6..5e2b1b0aff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt @@ -17,13 +17,19 @@ package org.matrix.android.sdk.api.cache sealed class CacheStrategy { - // Data is always fetched from the server + /** + * Data is always fetched from the server + */ object NoCache : CacheStrategy() - // Once data is retrieved, it is stored for the provided amount of time. - // In case of error, and if strict is set to false, the cache can be returned if available + /** + * Once data is retrieved, it is stored for the provided amount of time. + * In case of error, and if strict is set to false, the cache can be returned if available + */ data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : CacheStrategy() - // Once retrieved, the data is stored in cache and will be always get from the cache + /** + * Once retrieved, the data is stored in cache and will be always get from the cache + */ object InfiniteCache : CacheStrategy() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt index be139fd82b..4ded8bc47e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt @@ -37,7 +37,9 @@ sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) { data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString())) object SuccessError : Failure(RuntimeException(RuntimeException("SuccessResult is false"))) - // When server send an error, but it cannot be interpreted as a MatrixError + /** + * When server send an error, but it cannot be interpreted as a MatrixError + */ data class OtherServerError(val errorBody: String, val httpCode: Int) : Failure(RuntimeException("HTTP $httpCode: $errorBody")) data class RegistrationFlowError(val registrationFlowResponse: RegistrationFlowResponse) : Failure(RuntimeException(registrationFlowResponse.toString())) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt index 39de2cc712..0f8f4cd987 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt @@ -17,10 +17,14 @@ package org.matrix.android.sdk.api.session.crypto.verification sealed class VerificationTxState { - // Uninitialized state + /** + * Uninitialized state + */ object None : VerificationTxState() - // Specific for SAS + /** + * Specific for SAS + */ abstract class VerificationSasTxState : VerificationTxState() object SendingStart : VerificationSasTxState() @@ -38,18 +42,26 @@ sealed class VerificationTxState { object MacSent : VerificationSasTxState() object Verifying : VerificationSasTxState() - // Specific for QR code + /** + * Specific for QR code + */ abstract class VerificationQrTxState : VerificationTxState() - // Will be used to ask the user if the other user has correctly scanned + /** + * Will be used to ask the user if the other user has correctly scanned + */ object QrScannedByOther : VerificationQrTxState() object WaitingOtherReciprocateConfirm : VerificationQrTxState() - // Terminal states + /** + * Terminal states + */ abstract class TerminalTxState : VerificationTxState() object Verified : TerminalTxState() - // Cancelled by me or by other + /** + * Cancelled by me or by other + */ data class Cancelled(val cancelCode: CancelCode, val byMe: Boolean) : TerminalTxState() } From 268c41a0ee0b9aea4baef0ac02c415ec3bb640a6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 11 May 2022 15:16:35 +0200 Subject: [PATCH 094/349] Changelog --- changelog.d/5952.sdk | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog.d/5952.sdk diff --git a/changelog.d/5952.sdk b/changelog.d/5952.sdk new file mode 100644 index 0000000000..4973ec9c7c --- /dev/null +++ b/changelog.d/5952.sdk @@ -0,0 +1,3 @@ +- Some `val` have been changed to `fun` to increase their visibility in the generated documentation. Just add `()` if you were using them. +- `KeysBackupService.state` has been replaced by `KeysBackupService.getState()` +- SDK documentation improved From 8d74acf060d148fb799e66783046e816ea66795c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 11 May 2022 16:23:02 +0200 Subject: [PATCH 095/349] Fix post rebase issue --- .../org/matrix/android/sdk/common/CryptoTestHelper.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 348841313b..ac3da80fc5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -58,7 +58,7 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner -import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService +import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.toBase64NoPadding @@ -361,19 +361,19 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { ssssService.storeSecret( MASTER_KEY_SSSS_NAME, session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.master!!, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) ssssService.storeSecret( SELF_SIGNING_KEY_SSSS_NAME, session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.selfSigned!!, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) ssssService.storeSecret( USER_SIGNING_KEY_SSSS_NAME, session.cryptoService().crossSigningService().getCrossSigningPrivateKeys()!!.user!!, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) // set up megolm backup @@ -390,7 +390,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { ssssService.storeSecret( KEYBACKUP_SECRET_SSSS_NAME, secret, - listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)) + listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) } } From 8218d8f26797b00c4fb4975ed98a39565ed4a44d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 12 May 2022 14:44:10 +0200 Subject: [PATCH 096/349] Typo: isStucked -> isStuck --- .../sdk/api/session/crypto/keysbackup/KeysBackupService.kt | 2 +- .../internal/crypto/keysbackup/DefaultKeysBackupService.kt | 6 +++--- .../internal/crypto/keysbackup/KeysBackupStateManager.kt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 824ed1b992..dc8b03eaae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -207,7 +207,7 @@ interface KeysBackupService { get() = keysBackupVersion?.version fun isEnabled(): Boolean - fun isStucked(): Boolean + fun isStuck(): Boolean fun getState(): KeysBackupState // For gossiping diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index fe63529547..1319e54e32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -139,7 +139,7 @@ internal class DefaultKeysBackupService @Inject constructor( override fun isEnabled(): Boolean = keysBackupStateManager.isEnabled - override fun isStucked(): Boolean = keysBackupStateManager.isStucked + override fun isStuck(): Boolean = keysBackupStateManager.isStuck override fun getState(): KeysBackupState = keysBackupStateManager.state @@ -909,7 +909,7 @@ internal class DefaultKeysBackupService @Inject constructor( */ fun maybeBackupKeys() { when { - isStucked() -> { + isStuck() -> { // If not already done, or in error case, check for a valid backup version on the homeserver. // If there is one, maybeBackupKeys will be called again. checkAndStartKeysBackup() @@ -1012,7 +1012,7 @@ internal class DefaultKeysBackupService @Inject constructor( } override fun checkAndStartKeysBackup() { - if (!isStucked()) { + if (!isStuck()) { // Try to start or restart the backup only if it is in unknown or bad state Timber.w("checkAndStartKeysBackup: invalid state: ${getState()}") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt index 78ef958bbf..0614eceb16 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt @@ -49,7 +49,7 @@ internal class KeysBackupStateManager(private val uiHandler: Handler) { state == KeysBackupState.BackingUp // True if unknown or bad state - val isStucked: Boolean + val isStuck: Boolean get() = state == KeysBackupState.Unknown || state == KeysBackupState.Disabled || state == KeysBackupState.WrongBackUpVersion || From 827c7e58f6e6b4ba9a21840b3c3d1acffcb4351c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 12 May 2022 14:45:15 +0200 Subject: [PATCH 097/349] Package have been renamed, so also rename it here. Dokka does not complain about unknown package in this file :/ --- matrix-sdk-android/docs/packages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/docs/packages.md b/matrix-sdk-android/docs/packages.md index 98b0e0c034..19f7c15a7a 100644 --- a/matrix-sdk-android/docs/packages.md +++ b/matrix-sdk-android/docs/packages.md @@ -1,4 +1,4 @@ -# Package org.matrix.android.sdk._userstories +# Package org.matrix.android.sdk.userstories This package contains some user stories (**Us** prefix) of the SDK usage. You will find example of what it is possible to do with the SDK and the API which can be used to do it. From b86693580ed2944b76a91517115d20f080fab21b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 12 May 2022 14:57:39 +0200 Subject: [PATCH 098/349] `class` with `private constructor` instead of `object` --- .../java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt | 2 +- .../main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt | 2 +- .../org/matrix/android/sdk/userstories/Us150VerifySession.kt | 2 +- .../java/org/matrix/android/sdk/userstories/Us190SignOut.kt | 2 +- .../java/org/matrix/android/sdk/userstories/Us200RoomList.kt | 2 +- .../org/matrix/android/sdk/userstories/Us300RoomTimeline.kt | 2 +- .../android/sdk/userstories/Us350RoomTimelineFromPermalink.kt | 2 +- .../org/matrix/android/sdk/userstories/Us400RoomSendContent.kt | 2 +- .../org/matrix/android/sdk/userstories/Us500Notification.kt | 2 +- .../matrix/android/sdk/userstories/Us600SyncWithTheServer.kt | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt index 1eb926c54a..f0c2e42edb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * ### Required APIs: * - [org.matrix.android.sdk.api.Matrix] constructor */ -object Us000InitMatrix +class Us000InitMatrix private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt index fdd78737f8..91d82a78b7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt @@ -28,4 +28,4 @@ package org.matrix.android.sdk.userstories * - [org.matrix.android.sdk.api.auth.AuthenticationService.getLoginWizard] * - [org.matrix.android.sdk.api.auth.login.LoginWizard.login] */ -object Us100SignIn +class Us100SignIn private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt index 6ccee2e783..c26f2d45af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us150VerifySession +class Us150VerifySession private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt index fb50449148..de895ad710 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us190SignOut +class Us190SignOut private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt index acc73aa340..61b5e3384b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us200RoomList +class Us200RoomList private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt index 23a06ba27a..4c0db3fbcf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us300RoomTimeline +class Us300RoomTimeline private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt index 6d0ae32cca..2ca4f1ec2b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us350RoomTimelineFromPermalink +class Us350RoomTimelineFromPermalink private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt index 8938f0703d..854fcd2f87 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us400RoomSendContent +class Us400RoomSendContent private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt index 5d08ac2366..157b3112f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us500Notification +class Us500Notification private constructor() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt index f6532ae9d1..5202b75369 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt @@ -25,4 +25,4 @@ package org.matrix.android.sdk.userstories * #### Required APIs: * - TODO */ -object Us600SyncWithTheServer +class Us600SyncWithTheServer private constructor() From 0307e572c0803c2c9b5a675f9f608b179a3a123e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 16:25:29 +0200 Subject: [PATCH 099/349] Add note about API renaming --- changelog.d/5952.sdk | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.d/5952.sdk b/changelog.d/5952.sdk index 4973ec9c7c..4226aba136 100644 --- a/changelog.d/5952.sdk +++ b/changelog.d/5952.sdk @@ -1,3 +1,4 @@ - Some `val` have been changed to `fun` to increase their visibility in the generated documentation. Just add `()` if you were using them. - `KeysBackupService.state` has been replaced by `KeysBackupService.getState()` +- `KeysBackupService.isStucked` has been replaced by `KeysBackupService.isStuck()` - SDK documentation improved From 92d54dc73322fbce0c6dbaad34488348d81c7f0f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 20 May 2022 21:13:30 +0200 Subject: [PATCH 100/349] Fix compilation issue --- .../sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 1319e54e32..efd3bca824 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -341,7 +341,7 @@ internal class DefaultKeysBackupService @Inject constructor( override fun backupAllGroupSessions(progressListener: ProgressListener?, callback: MatrixCallback?) { - if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) { + if (!isEnabled() || backupOlmPkEncryption == null || keysBackupVersion == null) { callback?.onFailure(Throwable("Backup not enabled")) return } From 53c83ab8d839e46a9dea33512da99b4bee58b484 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 20 May 2022 21:22:47 +0200 Subject: [PATCH 101/349] Add missing punctuation --- .../auth/registration/RegistrationResult.kt | 12 ++++++------ .../android/sdk/api/auth/registration/Stage.kt | 14 +++++++------- .../android/sdk/api/cache/CacheStrategy.kt | 4 ++-- .../matrix/android/sdk/api/failure/Failure.kt | 2 +- .../crypto/keysbackup/KeysBackupState.kt | 18 +++++++++--------- .../crypto/model/RoomEncryptionTrustLevel.kt | 8 ++++---- .../crypto/verification/VerificationMethod.kt | 6 +++--- .../crypto/verification/VerificationTxState.kt | 12 ++++++------ .../sdk/api/session/room/send/SendState.kt | 16 ++++++++-------- .../session/threads/ThreadNotificationState.kt | 6 +++--- .../android/sdk/userstories/Us000InitMatrix.kt | 2 +- .../android/sdk/userstories/Us100SignIn.kt | 2 +- .../sdk/userstories/Us150VerifySession.kt | 2 +- .../android/sdk/userstories/Us190SignOut.kt | 2 +- .../android/sdk/userstories/Us200RoomList.kt | 2 +- .../sdk/userstories/Us300RoomTimeline.kt | 2 +- .../Us350RoomTimelineFromPermalink.kt | 2 +- .../sdk/userstories/Us400RoomSendContent.kt | 2 +- .../sdk/userstories/Us500Notification.kt | 2 +- .../sdk/userstories/Us600SyncWithTheServer.kt | 2 +- 20 files changed, 59 insertions(+), 59 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt index f1639d2a09..9e6b2b3ad9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationResult.kt @@ -19,30 +19,30 @@ package org.matrix.android.sdk.api.auth.registration import org.matrix.android.sdk.api.session.Session /** - * Either a session or an object containing data about registration stages + * Either a session or an object containing data about registration stages. */ sealed class RegistrationResult { /** - * The registration is successful, the [Session] is provided + * The registration is successful, the [Session] is provided. */ data class Success(val session: Session) : RegistrationResult() /** - * The registration still miss some steps. See [FlowResult] to know the details + * The registration still miss some steps. See [FlowResult] to know the details. */ data class FlowResponse(val flowResult: FlowResult) : RegistrationResult() } /** - * Information about the missing and completed [Stage] + * Information about the missing and completed [Stage]. */ data class FlowResult( /** - * List of missing stages + * List of missing stages. */ val missingStages: List, /** - * List of completed stages + * List of completed stages. */ val completedStages: List ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt index ce834b976d..281b0c2808 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/Stage.kt @@ -17,38 +17,38 @@ package org.matrix.android.sdk.api.auth.registration /** - * Registration stages + * Registration stages. */ sealed class Stage(open val mandatory: Boolean) { /** - * m.login.recaptcha stage + * m.login.recaptcha stage. */ data class ReCaptcha(override val mandatory: Boolean, val publicKey: String) : Stage(mandatory) /** - * m.login.email.identity stage + * m.login.email.identity stage. */ data class Email(override val mandatory: Boolean) : Stage(mandatory) /** - * m.login.msisdn stage + * m.login.msisdn stage. */ data class Msisdn(override val mandatory: Boolean) : Stage(mandatory) /** * m.login.dummy, can be mandatory if there is no other stages. In this case the account cannot be created by just sending a username - * and a password, the dummy stage has to be done + * and a password, the dummy stage has to be done. */ data class Dummy(override val mandatory: Boolean) : Stage(mandatory) /** - * Undocumented yet: m.login.terms stage + * Undocumented yet: m.login.terms stage. */ data class Terms(override val mandatory: Boolean, val policies: TermPolicies) : Stage(mandatory) /** - * For unknown stages + * For unknown stages. */ data class Other(override val mandatory: Boolean, val type: String, val params: Map<*, *>?) : Stage(mandatory) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt index 5e2b1b0aff..ddf76d6e42 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/cache/CacheStrategy.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.cache sealed class CacheStrategy { /** - * Data is always fetched from the server + * Data is always fetched from the server. */ object NoCache : CacheStrategy() @@ -29,7 +29,7 @@ sealed class CacheStrategy { data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : CacheStrategy() /** - * Once retrieved, the data is stored in cache and will be always get from the cache + * Once retrieved, the data is stored in cache and will be always get from the cache. */ object InfiniteCache : CacheStrategy() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt index 4ded8bc47e..7d4f553bed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt @@ -38,7 +38,7 @@ sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) { object SuccessError : Failure(RuntimeException(RuntimeException("SuccessResult is false"))) /** - * When server send an error, but it cannot be interpreted as a MatrixError + * When server send an error, but it cannot be interpreted as a MatrixError. */ data class OtherServerError(val errorBody: String, val httpCode: Int) : Failure(RuntimeException("HTTP $httpCode: $errorBody")) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt index c4392ef9f1..a867d573de 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupState.kt @@ -52,50 +52,50 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup */ enum class KeysBackupState { /** - * Need to check the current backup version on the homeserver + * Need to check the current backup version on the homeserver. */ Unknown, /** - * Checking if backup is enabled on homeserver + * Checking if backup is enabled on homeserver. */ CheckingBackUpOnHomeserver, /** - * Backup has been stopped because a new backup version has been detected on the homeserver + * Backup has been stopped because a new backup version has been detected on the homeserver. */ WrongBackUpVersion, /** - * Backup from this device is not enabled + * Backup from this device is not enabled. */ Disabled, /** * There is a backup available on the homeserver but it is not trusted. - * It is not trusted because the signature is invalid or the device that created it is not verified + * It is not trusted because the signature is invalid or the device that created it is not verified. * Use [KeysBackup.getKeysBackupTrust()] to get trust details. * Consequently, the backup from this device is not enabled. */ NotTrusted, /** - * Backup is being enabled: the backup version is being created on the homeserver + * Backup is being enabled: the backup version is being created on the homeserver. */ Enabling, /** - * Backup is enabled and ready to send backup to the homeserver + * Backup is enabled and ready to send backup to the homeserver. */ ReadyToBackUp, /** - * e2e keys are going to be sent to the homeserver + * e2e keys are going to be sent to the homeserver. */ WillBackUp, /** - * e2e keys are being sent to the homeserver + * e2e keys are being sent to the homeserver. */ BackingUp } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt index d030988303..78724819a3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt @@ -21,22 +21,22 @@ package org.matrix.android.sdk.api.session.crypto.model */ enum class RoomEncryptionTrustLevel { /** - * No one in the room has been verified -> Black shield + * No one in the room has been verified -> Black shield. */ Default, /** - * There are one or more device un-verified -> the app should display a red shield + * There are one or more device un-verified -> the app should display a red shield. */ Warning, /** - * All devices in the room are verified -> the app should display a green shield + * All devices in the room are verified -> the app should display a green shield. */ Trusted, /** - * e2e is active but with an unsupported algorithm + * e2e is active but with an unsupported algorithm. */ E2EWithUnsupportedAlgorithm } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt index b3758c364b..0ab47a2ecd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationMethod.kt @@ -21,17 +21,17 @@ package org.matrix.android.sdk.api.session.crypto.verification */ enum class VerificationMethod { /** - * Use it when your application supports the SAS verification method + * Use it when your application supports the SAS verification method. */ SAS, /** - * Use it if your application is able to display QR codes + * Use it if your application is able to display QR codes. */ QR_CODE_SHOW, /** - * Use it if your application is able to scan QR codes + * Use it if your application is able to scan QR codes. */ QR_CODE_SCAN } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt index 0f8f4cd987..30e4c66937 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTxState.kt @@ -18,12 +18,12 @@ package org.matrix.android.sdk.api.session.crypto.verification sealed class VerificationTxState { /** - * Uninitialized state + * Uninitialized state. */ object None : VerificationTxState() /** - * Specific for SAS + * Specific for SAS. */ abstract class VerificationSasTxState : VerificationTxState() @@ -43,25 +43,25 @@ sealed class VerificationTxState { object Verifying : VerificationSasTxState() /** - * Specific for QR code + * Specific for QR code. */ abstract class VerificationQrTxState : VerificationTxState() /** - * Will be used to ask the user if the other user has correctly scanned + * Will be used to ask the user if the other user has correctly scanned. */ object QrScannedByOther : VerificationQrTxState() object WaitingOtherReciprocateConfirm : VerificationQrTxState() /** - * Terminal states + * Terminal states. */ abstract class TerminalTxState : VerificationTxState() object Verified : TerminalTxState() /** - * Cancelled by me or by other + * Cancelled by me or by other. */ data class Cancelled(val cancelCode: CancelCode, val byMe: Boolean) : TerminalTxState() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt index bb4a649a95..d058ff2840 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendState.kt @@ -18,42 +18,42 @@ package org.matrix.android.sdk.api.session.room.send enum class SendState { /** - * The state is unknown + * The state is unknown. */ UNKNOWN, /** - * The event has not been sent + * The event has not been sent. */ UNSENT, /** - * The event is encrypting + * The event is encrypting. */ ENCRYPTING, /** - * The event is currently sending + * The event is currently sending. */ SENDING, /** - * The event has been sent + * The event has been sent. */ SENT, /** - * The event has been received from server + * The event has been received from server. */ SYNCED, /** - * The event failed to be sent + * The event failed to be sent. */ UNDELIVERED, /** - * The event failed to be sent because some unknown devices have been found while encrypting it + * The event failed to be sent because some unknown devices have been found while encrypting it. */ FAILED_UNKNOWN_DEVICES; diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt index 226e7cc12e..6825f8c279 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadNotificationState.kt @@ -21,17 +21,17 @@ package org.matrix.android.sdk.api.session.threads */ enum class ThreadNotificationState { /** - * There are no new message + * There are no new message. */ NO_NEW_MESSAGE, /** - * There is at least one new message + * There is at least one new message. */ NEW_MESSAGE, /** - * The is at least one new message that should be highlighted + * The is at least one new message that should be highlighted. * ex. "Hello @aris.kotsomitopoulos" */ NEW_HIGHLIGHTED_MESSAGE; diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt index f0c2e42edb..06c6cc9ef9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us000InitMatrix.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Init a Matrix object + * Init a Matrix object. * * ### Required APIs: * - [org.matrix.android.sdk.api.Matrix] constructor diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt index 91d82a78b7..f508a75db7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us100SignIn.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Sign in to an existing account + * Sign in to an existing account. * * #### Required APIs: * - [org.matrix.android.sdk.api.Matrix.authenticationService] diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt index c26f2d45af..ac56cc35dd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us150VerifySession.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Verify a Session after a Sign in + * Verify a Session after a Sign in. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt index de895ad710..0c74c0dfef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us190SignOut.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Sign out + * Sign out. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt index 61b5e3384b..1f0b2e4103 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us200RoomList.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Get the Room list + * Get the Room list. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt index 4c0db3fbcf..5db06f95f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us300RoomTimeline.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Display a Room timeline, and navigate backward and forward + * Display a Room timeline, and navigate backward and forward. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt index 2ca4f1ec2b..5e0f6d3b3d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us350RoomTimelineFromPermalink.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Display a Room timeline at a specific point + * Display a Room timeline at a specific point. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt index 854fcd2f87..3f72cd0b9e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us400RoomSendContent.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Send content to a room, including monitoring the sending state + * Send content to a room, including monitoring the sending state. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt index 157b3112f8..c5c2107fa6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us500Notification.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Get notified when new Events are received + * Get notified when new Events are received. * * #### Required APIs: * - TODO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt index 5202b75369..6b8fb87df7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/userstories/Us600SyncWithTheServer.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.userstories /** * ### Title - * Manage the sync with the server + * Manage the sync with the server. * * #### Required APIs: * - TODO From 97b2dd3d14ad46872c8b36a42aa5d7c878616cf1 Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Thu, 19 May 2022 19:11:54 +0000 Subject: [PATCH 102/349] Translated using Weblate (Catalan) Currently translated at 83.3% (1854 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ca/ --- vector/src/main/res/values-ca/strings.xml | 48 +++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index 157396781a..167b41d1dc 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -846,7 +846,7 @@ Ja existeix una còpia de seguretat al teu servidor Sembla que ja has configurat una còpia de seguretat de claus des d\'una altra sessió. Vols reemplaçar-la amb la que estàs creant\? Reemplaçar - Aturar + Atura Comprovant l\'estat de la còpia de seguretat Verificat! Entesos @@ -1633,9 +1633,9 @@ Comparteix aquest codi amb la gent perquè puguin escanejar-lo, afegir-te i començar a xatejar amb tu. L\'usuari no s\'ha acceptat el consentiment. Envia el missatge proporcionat amb confetis - Envia el missatge proporcionat nevant - envia confetis 🎉 - envia una nevada❄️ + Envia el missatge proporcionat amb una nevada + ha enviat confetis 🎉 + ha enviat una nevada ❄️ El meu codi Comparteix el meu codi Escaneja un codi QR @@ -1651,8 +1651,8 @@ No tens permís per activar el xifrat en aquesta sala. Activa el xifrat d\'extrem a extrem… Editor de missatges - Envia l\'emoticona proporcionat pintat amb un arc de Sant Martí - Envia el missatge proporcionat pintat amb un arc de Sant Martí + Envia l\'emoticona proporcionat pintat en arc de Sant Martí + Envia el missatge proporcionat pintat en arc de Sant Martí Pot ser causat per diferents motius: \n \n• Has canviat la teva contrasenya des d\'una altra sessió. @@ -2051,4 +2051,38 @@ %d canvi a l\'ACL del servidor %d canvis a l\'ACL del servidor - + Privat + Públic + Espai privat per organitzar les teves sales + Espai públic (teu) + Espai privat (teu) + Afegeix espai + Espai privat + Espai públic + Actualitza una sala a una nova versió + A fora + Ocupat + Fora de línia + Pausa %1$s + Pausa missatge de veu + Deixa d\'ignorar un usuari, es mostraran els nous missatges + Reprodueix %1$s + %1$d minuts %2$d segons + %1$s, %2$s, %3$s + Missatge de veu (%1$s) + No pots respondre o editar mentre el missatge de veu està actiu + No es pot enregistrar missatge de veu + Aquest missatge de veu no es pot reproduir + Clica l\'enregistrament per aturar-lo o escoltar-lo + %1$ds restants + Manté per enregistrar, deixa anar per enviar + Elimina enregistrament + Enregistrant missatge de veu + Atura l\'enregistrament + Reprodueix missatge de veu + Llisca per cancel·lar + Enregistra missatge de veu + S\'ha produït un error en provar d\'entrar a: %s + Actualitza a la versió de sala recomanada + Aquesta sala té la versió %s, la qual està marcada com a no estable pel servidor. + \ No newline at end of file From 422487ea9fe61d3afd17a49a2401e00f9d428aa5 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 18 May 2022 06:11:11 +0000 Subject: [PATCH 103/349] Translated using Weblate (Czech) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- vector/src/main/res/values-cs/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 1ecc1c26f6..a098db1689 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2291,7 +2291,7 @@ Nastaví název místnosti Přestane ignorovat uživatele a zobrazí jeho zprávy Ignoruje uživatele a skrývá jeho zprávy - Nedostupný + Pryč Offline Online Naslouchání oznámením @@ -2378,7 +2378,7 @@ Otevřít fotoaparát Váš systém bude automaticky odesílat chybové protokoly, když dojde k chybě dešifrování Automaticky nahlašovat chyby dešifrování. - Přepsat barvu přezdívky + Přepsat barvu zobrazovaného jména Již mám účet Bezpečené zasílání zpráv. Máte vše pod kontrolou. @@ -2537,4 +2537,8 @@ \n \nTato akce povede k restartování aplikace a může trvat nějakou dobu. Požadavek na počáteční synchronizaci - + Zobrazit nejnovější informace o uživateli + Zobrazit nejnovější informace o profilu (avatar a zobrazované jméno) u všech zpráv. + Zaneprázdněn + Záloha má platný podpis tohoto uživatele. + \ No newline at end of file From aac075fa89b4042fb5e3c5ea25aa200472fdbee7 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 20 May 2022 17:01:02 +0000 Subject: [PATCH 104/349] Translated using Weblate (Spanish) Currently translated at 99.8% (2221 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/es/ --- vector/src/main/res/values-es/strings.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index ba5a8dfc02..d609dad45b 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -2486,4 +2486,8 @@ \n \nTen en cuenta que esta acción reiniciará la aplicación y podría tardar algo de tiempo. Petición inicial de sincronización - + La copia de seguridad tiene una firma válida de este usuario. + Mostrar la última información del perfil (avatar y nick) para todos los mensajes. + Mostrar última información del usuario + Ocupado + \ No newline at end of file From 49acc6704f34f7e807ac918b2119114b0b33d19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 17 May 2022 18:41:45 +0000 Subject: [PATCH 105/349] Translated using Weblate (Estonian) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- vector/src/main/res/values-et/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 8aa1dfb09b..5422d18097 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2251,7 +2251,7 @@ Määrab jututoa nime Lõpeta kasutaja eiramine ja näita edaspidi tema sõnumeid Eirab kasutajat peites kõik tema sõnumid sinu eest - Pole leitav + Eemal Võrgust väljas Võrgus Vali koduserver @@ -2333,7 +2333,7 @@ populaarsem valik Kui sõnumite dekrüptimisel tekib viga, siis rakendus saadab selle kohta automaatse teate arendajatele Automaatselt teata dekrüptimise vigadest. - Asenda hüüdnime värvid + Asenda kuvatava nime värvid Mul on kasutajakonto juba olemas Turvaline sõnumivahetus. Sul on kontroll oma andmete üle. @@ -2490,4 +2490,8 @@ \n \nPalun arvesta, et selle käigus rakendus käivitub uuesti ja see võib aega võtta. Alusandmete sünkroniseerimise päring - + Näita kõikide sõnumite puhul viimast profiili teavet (tunnuspilt ja kuvatav nimi). + Näita viimast kasutajateavet + Hõivatud + Varukoopial on kehtiv allkiri sellelt kasutajalt. + \ No newline at end of file From 7ff956678838afed83df22b03e3be0c103f02a59 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 18 May 2022 09:12:55 +0000 Subject: [PATCH 106/349] Translated using Weblate (Persian) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/ --- vector/src/main/res/values-fa/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 171a145eb6..a35f632991 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2251,7 +2251,7 @@ نام اتاق را تنظیم می‌کند به کاربری چشم گشوده و پیام‌های بعدیش را نشان می‌دهد از کاربری چشم‌پوشی کرده و پیام‌هایش را از شما پنهان می‌کند - ناموجود + بیرون برون‌خط برخط گزینش کارساز خانگی @@ -2359,7 +2359,7 @@ نتایج تنها هنگامی که نظرسنجی را پایان دهید آشکار می‌شوند رأی دهندگان به محض دادن رأی، نتایج را می‌بینند رمزنگاری بد پیکربندی شده - پایمالی رنگ نام مستعار + پایمالی رنگ نام نمایشی لطفاً برای بازگردانی رمزنگاری به یه وضعیتی معتبر، با مدیری تماس بگیرید. رمزنگاری بد پیکربندی شده. رمزنگاشتهٔ سرتاسری و بدون نیاز به شماره تلفن. بدون تبلیغات یا داده‌کاوی. @@ -2490,4 +2490,8 @@ هم‌رسانی صفحه - برخی کاربران ناچشم‌پوشی شده‌اند درخواست همگام سازی نخستین - + نمایش جدیدترین اطَلاعات نمایه (چهرک و نام نمایشی) برای تمامی پیام‌ها. + نمایش جدیدترین اطّلاعات کاربری + مشغول + پشتیبان امضای معتبری از این کاربر دارد. + \ No newline at end of file From d307349ae20b2924d3c458951cb7504946e497e2 Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 18 May 2022 18:33:40 +0000 Subject: [PATCH 107/349] Translated using Weblate (Indonesian) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- vector/src/main/res/values-in/strings.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index a8a457b4af..efb60739d7 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2213,7 +2213,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengubah avatar ruangan saat ini Mengubah avatar Anda di ruangan saat ini saja Menampilkan - Tidak Tersedia + Tidak tersedia Luring Daring Pilih homeserver @@ -2445,4 +2445,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. \n \nDicatat bahwa tindakan ini akan memulai ulang aplikasinya dan mungkin membutuhkan beberapa waktu. Permintaan sinkronisasi awal - + Tampilkan info profil (avatar dan nama tampilan) terkini untuk semua pesan. + Tampilkan info pengguna terkini + Sibuk + Cadangan memiliki tandatangan yang valid dari pengguna ini. + \ No newline at end of file From 165b8d1b93d3c6faa9d3f1afb29cd8712bf30ec0 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 18 May 2022 08:52:34 +0000 Subject: [PATCH 108/349] Translated using Weblate (Italian) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- vector/src/main/res/values-it/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 3eec2c5f14..0dc9c1a240 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2242,7 +2242,7 @@ Imposta il nome della stanza Smetti di ignorare un utente, mostrando i suoi messaggi successivi Ignora un utente, non mostrandoti i suoi messaggi - Non disponibile + Assente Offline Online Scegli homeserver @@ -2324,7 +2324,7 @@ Apri fotocamera Il tuo sistema invierà automaticamente i log quando si verifica un errore di decifrazione Auto-segnala errori di decifrazione. - Sovrascrivi colore nick + Sovrascrivi colore nome visualizzato Ho già un account Messaggistica sicura. Tu hai il controllo. @@ -2481,4 +2481,8 @@ \n \nNota che questa azione riavvierà l\'app e potrebbe richiedere del tempo. Richiesta di sincronizzazione iniziale - + Mostra le informazioni di profilo più recenti (avatar e nome visualizzato) per tutti i messaggi. + Mostra info utente più recenti + Occupato + Il backup ha una firma valida da questo utente. + \ No newline at end of file From 9710447ea3dafc069446aacb0cd7a86eff788bfc Mon Sep 17 00:00:00 2001 From: Piotr Strebski Date: Fri, 20 May 2022 09:16:17 +0000 Subject: [PATCH 109/349] Translated using Weblate (Polish) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- vector/src/main/res/values-pl/strings.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index d6fef1c620..c9a7c9acf7 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2258,7 +2258,7 @@ Edytuj treść Poznaj stan pokoju Narzędzia deweloperskie - Niedostępny + Nieobecny Pokój publiczny Nie powiadamiaj Powiadom bez dźwięku @@ -2321,7 +2321,7 @@ Usunąłeś(aś) %1$s jako adresy tego pokoju. Usunąłeś(aś) %1$s jako adresy tego pokoju. - Nadpisz kolor nicku + Zastąp kolor wyświetlanej nazwy Posiadam już konto Połącz się z każdym. Ty jesteś w kontroli. @@ -2583,4 +2583,5 @@ Udostępnij ekran - Niektórzy użytkownicy przestali być ignorowani Początkowe żądanie synchronizacji - + Kopia zapasowa ma poprawny podpis tego użytkownika. + \ No newline at end of file From 946353aeb9f57d008151349da2b7ae84f837a907 Mon Sep 17 00:00:00 2001 From: Didek Date: Wed, 18 May 2022 22:25:44 +0000 Subject: [PATCH 110/349] Translated using Weblate (Polish) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- vector/src/main/res/values-pl/strings.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index c9a7c9acf7..23b1ef5d0c 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -736,8 +736,8 @@ Zaproszenia, usunięcia i bany pozostają nienaruszone. Wysyłaj wiadomości za pomocą klawisza enter Przycisk enter na klawiaturze programowej wyśle wiadomość zamiast wprowadzania łamanania linii - Znajdź - Zarządzaj ustawieniami wyszukiwania. + Ustawienia wyszukiwania + Ustal jak inni mogą odnaleść twoje konto. Media Domyślne źródło mediów Odzyskiwanie zaszyforwanych wiadomości @@ -1619,7 +1619,7 @@ Jeżeli chcesz zresetować kod PIN, naciśnij Zapomnij kod PIN aby wylogować i zresetować. Włącz kod PIN Skonfiguruj ochronę - Ochrona dostępu poprzez kod PIN oraz biometrię. + Blokada aplikacji poprzez kod PIN oraz biometrię. Ochrona dostępu Aby zresetować kod PIN musisz się ponownie zalogować i utworzyć nowy. Nowy kod PIN @@ -2584,4 +2584,7 @@ - Niektórzy użytkownicy przestali być ignorowani Początkowe żądanie synchronizacji Kopia zapasowa ma poprawny podpis tego użytkownika. + Pokazuj aktualny stan profilu (obraz i nazwa) w całej historii konwersacji. + Pokazuj najnowsze informacje o użytkowniku + Zajęty \ No newline at end of file From b12e0cd9f3462bf3b35eccef75eea56a99162d74 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 17 May 2022 16:14:02 +0000 Subject: [PATCH 111/349] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 97896dec64..e689f4be82 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -2251,7 +2251,7 @@ Define o nome da sala Para de ignorar um/uma usuário(a), mostrando as mensagens dele/dela de agora em diante Ignora um/uma usuário(a), escondendo as mensagens dele/dela de você - Indisponível + Fora Offline Online Escolher servidorcasa @@ -2333,7 +2333,7 @@ Abrir câmera Seu sistema vai automaticamente enviar logs quando um erro incapaz de decriptar ocorre Auro Reportar Erros de Decriptação. - Sobrepor cor de nick + Sobrepor cor de nome de exibição Eu já tenho uma conta Mensageria segura. Você está em controle. @@ -2490,4 +2490,8 @@ \n \nNote que esta ação vai recomeçar o app e pode levar algum tempo. Requisição de sinc inicial - + Mostrar a info de perfil mais recente (avatar e nome de exibição) para todas as mensagens. + Mostrar info de usuária(o) mais recente + Ocupada(o) + Backup tem uma assinatura válida desta(e) usuária(o). + \ No newline at end of file From 79858a6560c1441db112d672e5e1d922e65f0be1 Mon Sep 17 00:00:00 2001 From: homocomputeris Date: Tue, 17 May 2022 22:54:32 +0000 Subject: [PATCH 112/349] Translated using Weblate (Russian) Currently translated at 97.6% (2172 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- vector/src/main/res/values-ru/strings.xml | 62 ++++++++++++++++------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index cbc4bea123..f822cf05f3 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -46,7 +46,7 @@ Начальная синхронизация: \nИмпорт комнат Начальная синхронизация: -\nЗагрузка ваших бесед +\nВаши беседы загружаются \nЕсли вы присоединились к большому количеству комнат, это может занять некоторое время Начальная синхронизация: \nИмпорт приглашенных комнат @@ -417,9 +417,7 @@ Новый пароль Не удалось обновить пароль Пароль был обновлен - Отображать сообщения пользователя %s\? -\n -\nУчтите, что это действие перезапустит приложение и может занять некоторое время. + Показать все сообщения %s\? Выберите страну Тема Доступ к истории комнаты @@ -531,7 +529,7 @@ Вас заблокировал %2$s в %1$s Причина: %1$s Встряхните устройство, чтобы сообщить об ошибке - Список участников + Участники %d комната %d комнаты @@ -610,8 +608,8 @@ Изменить ваше отображаемое имя Вкл/выкл markdown Эта комната была заменена и больше не активна. - Этот разговор продолжается здесь - Эта комната является продолжением другого разговора + Беседа продолжается здесь + Эта комната — продолжение другой беседы Нажмите здесь для просмотра старых сообщений Присоединиться к комнате с указанным адресом Для исправления управления приложениями Matrix @@ -901,7 +899,7 @@ Вы в теме! У вас больше нет непрочитанных сообщений Беседы - Здесь будут отображаться ваши диалоги. Нажмите + внизу справа, чтобы начать что-то. + Здесь будут ваши диалоги. Нажмите кнопку «+» внизу справа, чтобы начать беседу. Комнаты Здесь будут отображаться ваши комнаты. Коснитесь + внизу справа, чтобы найти существующие или создать свои. Реакции @@ -961,7 +959,7 @@ (изменено) Изменение сообщения Изменения не найдены - Отфильтровывать разговоры… + Отфильтровать беседы… Не можете найти то, что ищете\? Создать новую комнату Отправить новое сообщение в диалог @@ -1073,7 +1071,7 @@ Введите ключевые слова, чтобы найти реакцию. Долгий клик по комнате покажет дополнительные опции Непрочитанные сообщения - Это ваш разговор. Владейте им. + Это ваша переписка. Контролируйте её. Общайтесь с людьми напрямую или в группах Начнем Выберите сервер @@ -1307,7 +1305,7 @@ \n \nВы можете отменить это действие в любое время в общих настройках. Перестать игнорировать пользователя - Если вы перестанете игнорировать этого пользователя, то все его сообщения вновь будут отображаться. + Если вы перестанете игнорировать этого пользователя, то вы увидите все его сообщения снова. Отменить приглашение Вы уверены, что хотите отменить приглашение для этого пользователя\? Выгнать пользователя @@ -1354,7 +1352,7 @@ Вы не игнорируете никаких пользователей Вы сделали комнату доступной для всех, у кого есть ссылка. Вы сделали комнату только по приглашению. - Сохраняйте конфиденциальность разговоров с помощью шифрования + Храните тайну переписки с помощью шифрования Расширьте и персонализируйте свой опыт использования Присоединяйтесь к миллионам бесплатно на крупнейшем публичном сервере Войти в %1$s @@ -1824,7 +1822,7 @@ Добавить людей "Тема: " Добавьте тему - Это начало разговора. + Это начало беседы. Это начало %s. У вас нет разрешения на включение шифрования в этой комнате. Создание комнаты… @@ -2404,11 +2402,11 @@ Создать учетную запись Обмен сообщениями для вашей команды. Сквозное шифрование не требующее номера телефона. Нет рекламы или сбора данных. - Выбор где хранятся ваши разговоры дает вам власть и независимость. Подключено с помощью Matrix. + Решайте самостоятельно и независимо, где хранить беседы. Благодаря Matrix. Безопасное и независимое общение, обеспечивающее вам такой же уровень конфиденциальности, как при личном общении в вашем собственном доме. Безопасный обмен сообщениями. Ваше управление. - Ваши собственные разговоры. + Контролируйте свою переписку. Местоположение Вы согласны отправить эту информацию\? Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию (электронную почту и номера телефонов) на сервер обнаружения. Мы хешируем ваши данные перед отправкой для обеспечения конфиденциальности. @@ -2441,7 +2439,7 @@ Не могу связаться с домашним сервером на URL %s. Пожалуйста, проверьте вашу ссылку или выберите домашний сервер вручную. Не сейчас Включить - Поиск уведомлений + Ожидание уведомлений Вам не разрешено подключаться к этой комнате Организуйте обсуждение с помощью веток Показать все ветки, в которых вы участвуете @@ -2468,7 +2466,7 @@ Команда «%s» распознается, но не поддерживается в ветках. Из ветки Совет: нажмите и удерживайте сообщение и используйте «%s». - Ветки помогают хранить ваши разговоры по темам и легко отслеживать их. + Ветки помогают не терять нить беседы, и за ними легко следить. Мои ветки Показать все ветки этой комнаты Фильтр @@ -2494,4 +2492,32 @@ %d изменений ACL сервера %d изменений ACL сервера - + Поехали! + Его можно изменить позже + Добавить аватар + Его можно изменить позже + Имя для показа + Показывается, когда вы отправляете сообщения. + Выберите имя для показа + Ваш аккаунт «%s» создан. + Поздравляем! + Домой + Персонализировать + БЕТА + Отзывы на бета-версию веток + Оставить отзыв + БЕТА + Если включено, для других вы всегда будете выглядеть, как в офлайне, даже при использовании приложения. + Офлайн-режим + Бета-версия веток + Бета-версия веток + Ветки почти в бете 🎉 + Остановить демонстрацию экрана + Демонстрировать экран + Узнать больше + Попробуйте + Отключить + - Несколько пользователей больше не игнорируются + Начальный запрос на синхронизацию + Ветки помогают не терять нить беседы, и за ними легко следить.%sВключение веток обновит приложение. Может занять продолжительное время. + \ No newline at end of file From 096e51951a8d8c2728795b9023a1bd0fbf25274a Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 17 May 2022 16:20:52 +0000 Subject: [PATCH 113/349] Translated using Weblate (Slovak) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- vector/src/main/res/values-sk/strings.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index a7a9f152fd..628d02ccd4 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2385,7 +2385,7 @@ Hľadať názov Spätnú väzbu sa nepodarilo odoslať (%s) Zobraziť informácie o ladení chýb na obrazovke - Nahradiť farbu prezývky + Nahradiť farbu zobrazovaného mena Chcete sa pripojiť k existujúcemu serveru\? Udalosť bola upravená administrátorom miestnosti, dôvod: %1$s Táto miestnosť je momentálne neprístupná. @@ -2537,4 +2537,8 @@ \n \nUpozorňujeme, že táto akcia spôsobí reštart aplikácie a môže chvíľu trvať. Úvodná žiadosť o synchronizáciu - + Zobraziť najnovšie informácie o profile (obrázok a zobrazované meno) pre všetky správy. + Zobraziť najnovšie informácie o používateľovi + Obsadený/zaneprázdnený + Zálohovanie má platný podpis od tohto používateľa. + \ No newline at end of file From 3826b7ba2865262eae3f6ff5fee53f1e23817135 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 20 May 2022 16:32:24 +0000 Subject: [PATCH 114/349] Translated using Weblate (Swedish) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 5a05f73cf4..7c3eb549d8 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2251,7 +2251,7 @@ Slutför inställning av upptäckbarhet. Du använder för närvarande ingen identitetsserver. För att bjuda in teammedlemmar och kunna upptäckas av dem, konfigurera en nedan. Bjud in med användarnamn eller e-postadress - Otillgänglig + Borta Offline Online Välj hemserver @@ -2490,4 +2490,8 @@ \n \nObservera att detta startar om appen, och kan ta ett tag. Förfrågan om inledande synk - + Visa den senaste profilinfon (avatar och visningsnamn) för alla meddelandena. + Visa senaste användarinfon + Upptagen + Säkerhetskopian har en giltig signatur från den här användaren. + \ No newline at end of file From b784c0fcc27da21a29af11c2bccf0cd2f8489b35 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 17 May 2022 17:38:47 +0000 Subject: [PATCH 115/349] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- vector/src/main/res/values-uk/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index d9847bbb81..f3290460b4 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -2155,7 +2155,7 @@ Надіслати подію стану Надіслати власну подію Дізнатися стан кімнати - Недоступний + Відсутній Не в мережі У мережі Перегляд підтвердження прочитання @@ -2421,7 +2421,7 @@ Відкрити камеру Ваша система автоматично надсилатиме журнали, коли виникне помилка неможливості розшифрування Автозвіт про помилки шифрування. - Замінити колір псевдоніма + Замінити колір показуваного імені Я вже маю обліковий запис Захищене спілкування. Ви контролюєте все. @@ -2582,4 +2582,8 @@ \n \nЗауважте, що ця дія перезапустить застосунок, і це може тривати деякий час. Початковий запит синхронізації - + Показати найновіші відомості про профіль (аватар і показуване ім\'я) для всіх повідомлень. + Показати найновіші відомості про користувача + Зайнятий + Резервна копія має дійсний підпис від цього користувача. + \ No newline at end of file From 7d9cb1dc0cd7d656b2734797487e4e81ed55ea83 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 18 May 2022 03:37:31 +0000 Subject: [PATCH 116/349] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- vector/src/main/res/values-zh-rTW/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 8fd51266f5..fe77ba3f0a 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2211,7 +2211,7 @@ 設定聊天室名稱 停止忽略使用者,繼續顯示他們的訊息 忽略使用者,為您隱藏他們的訊息 - 不可用 + 離開 離線 線上 選擇家伺服器 @@ -2288,7 +2288,7 @@ 開啟攝影機 發生無法解密錯誤時,您的系統將會自動傳送紀錄檔 自動回報解密錯誤。 - 覆寫暱稱色彩 + 覆寫顯示名稱色彩 我已有一個帳號 安全傳送訊息。 您已掌控了您的資料。 @@ -2443,4 +2443,8 @@ \n \n注意,此動作將會重新啟動應用程式,並可能需要一些時間。 初始同步請求 - + 顯示所有訊息的最新個人檔案資訊(大頭照與顯示名稱)。 + 顯示最新的使用者資訊 + 忙碌 + 備份具有來自該使用者的有效簽名。 + \ No newline at end of file From ddd6fc214fa04ec4ffc65235c64a22a0a1e6ea76 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 18 May 2022 13:57:48 +0000 Subject: [PATCH 117/349] Translated using Weblate (Spanish) Currently translated at 61.6% (37 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/es/ --- fastlane/metadata/android/es-ES/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/es-ES/changelogs/40104140.txt diff --git a/fastlane/metadata/android/es-ES/changelogs/40104140.txt b/fastlane/metadata/android/es-ES/changelogs/40104140.txt new file mode 100644 index 0000000000..595cd6b3d4 --- /dev/null +++ b/fastlane/metadata/android/es-ES/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Cambios principales en esta versión: Mejoras en la administración de usuarios ignorados. Varias correciones de bugs y mejoras en la estabilidad. +Registro de cambios: https://github.com/vector-im/element-android/releases From a7a1645abe516310630648a8df38a21351414c08 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 17 May 2022 16:11:24 +0000 Subject: [PATCH 118/349] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/ --- fastlane/metadata/android/pt-BR/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40104140.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104140.txt b/fastlane/metadata/android/pt-BR/changelogs/40104140.txt new file mode 100644 index 0000000000..ed1a53c910 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Melhorar gerenciamento de usuárias(os) ignoradas(os). Vários consertos de bugs e melhorias de estabilidade. +Changelog completo: https://github.com/vector-im/element-android/releases From 69aabb56a0a377063d1e8138eb32908911beba13 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 17 May 2022 16:17:15 +0000 Subject: [PATCH 119/349] Translated using Weblate (Slovak) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40104140.txt diff --git a/fastlane/metadata/android/sk/changelogs/40104140.txt b/fastlane/metadata/android/sk/changelogs/40104140.txt new file mode 100644 index 0000000000..e1c85961a4 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Zlepšenie správy ignorovaných používateľov. Rôzne opravy chýb a vylepšenia stability. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From afa0090c78e48d056957fb7b3558eba138de2527 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 20 May 2022 16:33:08 +0000 Subject: [PATCH 120/349] Translated using Weblate (Swedish) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40104140.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104140.txt b/fastlane/metadata/android/sv-SE/changelogs/40104140.txt new file mode 100644 index 0000000000..9b58878dfb --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Förbättra hantering av ignorerade användare. Diverse buggfixar och stabilitetsförbättringar. +Full ändringslogg: https://github.com/vector-im/element-android/releases From 311374d6422690925dc3003de647f900adc0d483 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 17 May 2022 17:36:45 +0000 Subject: [PATCH 121/349] Translated using Weblate (Ukrainian) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40104140.txt diff --git a/fastlane/metadata/android/uk/changelogs/40104140.txt b/fastlane/metadata/android/uk/changelogs/40104140.txt new file mode 100644 index 0000000000..293ad117e4 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Основні зміни у цій версії: Удосконалено керування нехтуваними користувачами. Різні виправлення помилок та поліпшення стабільності. +Вичерпний журнал змін: https://github.com/vector-im/element-android/releases From 90c78f1244e732cdc60cd924cbae1cb23a30f724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 17 May 2022 18:39:39 +0000 Subject: [PATCH 122/349] Translated using Weblate (Estonian) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40104140.txt diff --git a/fastlane/metadata/android/et/changelogs/40104140.txt b/fastlane/metadata/android/et/changelogs/40104140.txt new file mode 100644 index 0000000000..9000616f38 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: eiratud kasutajate parem haldus ning erinevate vigade parandused ja stabiilsust edendavad kohendused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From bda822d2e5727d56a79532f670be36d6c496bb6d Mon Sep 17 00:00:00 2001 From: random Date: Wed, 18 May 2022 08:53:15 +0000 Subject: [PATCH 123/349] Translated using Weblate (Italian) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/it/ --- fastlane/metadata/android/it-IT/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40104140.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40104140.txt b/fastlane/metadata/android/it-IT/changelogs/40104140.txt new file mode 100644 index 0000000000..ae367e72d0 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: migliorata la gestione degli utenti ignorati. Varie correzioni e miglioramenti della stabilità. +Cronologia completa: https://github.com/vector-im/element-android/releases From 182fae77da5a8d4e55ba73f702f26262169fb6be Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 18 May 2022 09:11:14 +0000 Subject: [PATCH 124/349] Translated using Weblate (Persian) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40104140.txt diff --git a/fastlane/metadata/android/fa/changelogs/40104140.txt b/fastlane/metadata/android/fa/changelogs/40104140.txt new file mode 100644 index 0000000000..cf5d7bc6ac --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104140.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: مدیریت بهبودیافتهٔ کاربران چشم‌پوشیده. رفع اشکال‌های مختلف و بهبودهای پایداری. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From cd27ea69bba269bfa9f662c002a61f0df2699f5d Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 18 May 2022 03:35:39 +0000 Subject: [PATCH 125/349] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/ --- fastlane/metadata/android/zh-TW/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40104140.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104140.txt b/fastlane/metadata/android/zh-TW/changelogs/40104140.txt new file mode 100644 index 0000000000..ff830dab7c --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104140.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:改善被忽略使用者的管理。多個臭蟲修復與穩定性改善。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From 62dd47b15dc548ded098ff1d15a4ead8bf2ca5a6 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 18 May 2022 06:11:46 +0000 Subject: [PATCH 126/349] Translated using Weblate (Czech) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/ --- fastlane/metadata/android/cs-CZ/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40104140.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104140.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104140.txt new file mode 100644 index 0000000000..d369efa9f2 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Zlepšení správy ignorovaných uživatelů. Opravy různých chyb a vylepšení stability. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From b1e045d911b6bf158c3aa12e88d83eb219d43d2c Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 18 May 2022 18:35:39 +0000 Subject: [PATCH 127/349] Translated using Weblate (Indonesian) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40104140.txt diff --git a/fastlane/metadata/android/id/changelogs/40104140.txt b/fastlane/metadata/android/id/changelogs/40104140.txt new file mode 100644 index 0000000000..174e8dcded --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Tingkatkan pengelolaan pengguna yang diabaikan. Beberapa perbaikan kutu dan stabilitas. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From 94f2640f5c7e74234e452bd82694560fef839ee6 Mon Sep 17 00:00:00 2001 From: Piotr Strebski Date: Fri, 20 May 2022 09:45:53 +0000 Subject: [PATCH 128/349] Translated using Weblate (Polish) Currently translated at 66.6% (40 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pl/ --- fastlane/metadata/android/pl-PL/changelogs/40101120.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40101130.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40101140.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40101150.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40101160.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40102000.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40102010.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40103000.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40103010.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40103020.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40103040.txt | 2 ++ fastlane/metadata/android/pl-PL/changelogs/40104140.txt | 2 ++ 13 files changed, 26 insertions(+) create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40101120.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40101130.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40101140.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40101150.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40101160.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40102000.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40102010.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40103000.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40103010.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40103020.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40103030.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40103040.txt create mode 100644 fastlane/metadata/android/pl-PL/changelogs/40104140.txt diff --git a/fastlane/metadata/android/pl-PL/changelogs/40101120.txt b/fastlane/metadata/android/pl-PL/changelogs/40101120.txt new file mode 100644 index 0000000000..6a62f1c6a9 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40101120.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: aktualizacja motywu i stylu oraz naprawa awarii po rozmowie wideo +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.12 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40101130.txt b/fastlane/metadata/android/pl-PL/changelogs/40101130.txt new file mode 100644 index 0000000000..ec8d488eb8 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40101130.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: głównie aktualizacja stabilności i poprawki błędów. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.13 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40101140.txt b/fastlane/metadata/android/pl-PL/changelogs/40101140.txt new file mode 100644 index 0000000000..c4c102da4a --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40101140.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: naprawienie problemu z zaszyfrowanymi wiadomościami. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.14 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40101150.txt b/fastlane/metadata/android/pl-PL/changelogs/40101150.txt new file mode 100644 index 0000000000..2eb1a3f018 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40101150.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: implementacja wiadomości głosowych w ustawieniach laboratorium. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.15 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40101160.txt b/fastlane/metadata/android/pl-PL/changelogs/40101160.txt new file mode 100644 index 0000000000..682da8be76 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40101160.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Naprawiono błąd podczas wysyłania zaszyfrowanej wiadomości, jeśli ktoś w pokoju się wyloguje. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.1.16 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40102000.txt b/fastlane/metadata/android/pl-PL/changelogs/40102000.txt new file mode 100644 index 0000000000..cdae0a4ba7 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40102000.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Wiadomość głosowa jest domyślnie włączona. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.2.0 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40102010.txt b/fastlane/metadata/android/pl-PL/changelogs/40102010.txt new file mode 100644 index 0000000000..0a825e8672 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40102010.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Wiele ulepszeń w VoIP i Przestrzeniach (nadal w wersji beta). +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.2.1 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103000.txt b/fastlane/metadata/android/pl-PL/changelogs/40103000.txt new file mode 100644 index 0000000000..8b408ced72 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Organizuj swoje pokoje za pomocą Przestrzeni! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103010.txt b/fastlane/metadata/android/pl-PL/changelogs/40103010.txt new file mode 100644 index 0000000000..0a49e7fa68 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103010.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Organizuj swoje pokoje za pomocą Przestrzeni! Wersja 1.3.1 naprawia awarię, która może wystąpić w wersji 1.3.0. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.1 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103020.txt b/fastlane/metadata/android/pl-PL/changelogs/40103020.txt new file mode 100644 index 0000000000..3e37f64b76 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103020.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Dodano obsługę Android Auto. Wiele poprawek błędów! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.2 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103030.txt b/fastlane/metadata/android/pl-PL/changelogs/40103030.txt new file mode 100644 index 0000000000..8f80d95b5a --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Uwidocznij politykę(-i) serwera tożsamości w ustawieniach. Tymczasowo usunięto obsługę Androida Auto. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103040.txt b/fastlane/metadata/android/pl-PL/changelogs/40103040.txt new file mode 100644 index 0000000000..13458a7b2d --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Dodanie obsługi obecności, dla pokoju wiadomości bezpośrednich (uwaga: obecność jest wyłączona na matrix.org). Dodano ponownie obsługę Androida Auto. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.4 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104140.txt b/fastlane/metadata/android/pl-PL/changelogs/40104140.txt new file mode 100644 index 0000000000..84ab57a2ac --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104140.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Poprawa zarządzania ignorowanymi użytkownikami. Różne poprawki błędów i ulepszenia stabilności. +Pełna lista zmian: https://github.com/vector-im/element-android/releases From 9779e9b9a5df2abdc986470f7bfda6870335862f Mon Sep 17 00:00:00 2001 From: anoloth Date: Thu, 19 May 2022 09:42:57 +0000 Subject: [PATCH 129/349] Translated using Weblate (Lao) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/lo/ --- vector/src/main/res/values-lo/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-lo/strings.xml b/vector/src/main/res/values-lo/strings.xml index 3d12927ac7..c22e5edf86 100644 --- a/vector/src/main/res/values-lo/strings.xml +++ b/vector/src/main/res/values-lo/strings.xml @@ -2018,7 +2018,7 @@ ສົ່ງເຫດການທີ່ກຳນົດເອງ ສຳຫຼວດສະຖານະຫ້ອງ ເຄື່ອງມືພັດທະນາ - ບໍ່ສາມາດໃຊ້ໄດ້ + ບໍ່ຢູ່ ອອຟລາຍ ອອນລາຍ ຫ້ອງສາທາລະນະ @@ -2243,7 +2243,7 @@ ກຳນົດເອງ ຜູ້ຄວບຄຸມ ຜູ້ເບິ່ງແຍງລະບົບ - ລົບລ້າງສີ nick + ໂຊທັບສີຂອງຊື່ນີ້ ກຳລັງອອກຈາກຫ້ອງ… ອອກໄປ ອອກຈາກຫ້ອງ @@ -2441,4 +2441,8 @@ ຢຸດການບັນທຶກ ຢຸດຂໍ້ຄວາມສຽງຊົ່ວຄາວ ຫຼິ້ນຂໍ້ຄວາມສຽງ - + ໂຊຂໍ້ມູນໂປຟາຍລ້າສຸດ (ໂຕກະຕູນ ແລະ ຊື່ສະແດງ) ສຳລັບທຸກໆຂໍ້ຄວາມ. + ໂຊຂໍ້ມູນຜູ້ໃຊ້ລ້າສຸດ + ບໍ່ວ່າງ + ແບັກອັບມີລາຍເຊັນຖືກຕ້ອງຈາກຜູ້ໃຊ້ນີ້. + \ No newline at end of file From 5e359101d243941423d3c321c66403aae80e8b87 Mon Sep 17 00:00:00 2001 From: anoloth Date: Thu, 19 May 2022 09:39:39 +0000 Subject: [PATCH 130/349] Translated using Weblate (Lao) Currently translated at 100.0% (60 of 60 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/lo/ --- fastlane/metadata/android/lo/changelogs/40104140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/lo/changelogs/40104140.txt diff --git a/fastlane/metadata/android/lo/changelogs/40104140.txt b/fastlane/metadata/android/lo/changelogs/40104140.txt new file mode 100644 index 0000000000..e8c8d84031 --- /dev/null +++ b/fastlane/metadata/android/lo/changelogs/40104140.txt @@ -0,0 +1,2 @@ +ການປ່ຽນແປງຫຼັກໃນສະບັບນີ້: ປັບປຸງການບໍລິຫານການລະເວັ້ນຜູ້ໃຊ້. ປັບປຸງບັກ ແລະຄວາມສະຖຽນ. +ບັນທຶກການປ່ຽນແປງສະບັບເຕັມ: https://github.com/vector-im/element-android/releases From 76fc3b53361068c4e9483720c26e9bc5dfe6b019 Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Sat, 21 May 2022 20:07:04 +0000 Subject: [PATCH 131/349] Translated using Weblate (Catalan) Currently translated at 83.3% (1855 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ca/ --- vector/src/main/res/values-ca/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index 167b41d1dc..8b3223ed26 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -2085,4 +2085,5 @@ S\'ha produït un error en provar d\'entrar a: %s Actualitza a la versió de sala recomanada Aquesta sala té la versió %s, la qual està marcada com a no estable pel servidor. + Només amb invitació, per tu o per equips \ No newline at end of file From c46aaa24a56b0ea531702f3216e3925ce0394ff0 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 10:40:52 +0200 Subject: [PATCH 132/349] Using @AndroidEntryPoint in Fragment --- .../main/java/im/vector/app/core/di/FragmentModule.kt | 5 ++--- .../location/live/map/LocationLiveMapViewFragment.kt | 9 ++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 6d42c83ac2..1f57031170 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,7 +64,6 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment -import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -995,8 +994,8 @@ interface FragmentModule { @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment - @Binds + /*@Binds @IntoMap @FragmentKey(LocationLiveMapViewFragment::class) - fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment + fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment*/ } diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt index 50526f2839..23b78e0f0f 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -24,6 +24,7 @@ import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args import com.mapbox.mapboxsdk.maps.MapboxMapOptions import com.mapbox.mapboxsdk.maps.SupportMapFragment +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseFragment @@ -34,9 +35,11 @@ import javax.inject.Inject /** * Screen showing a map with all the current users sharing their live location in room. */ -class LocationLiveMapViewFragment @Inject constructor( - private val urlMapProvider: UrlMapProvider, -) : VectorBaseFragment() { +@AndroidEntryPoint +class LocationLiveMapViewFragment : VectorBaseFragment() { + + @Inject + lateinit var urlMapProvider: UrlMapProvider private val args: LocationLiveMapViewArgs by args() From 721d7cb6a0387925568a0acd1955fe0efd46e160 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 11:30:35 +0200 Subject: [PATCH 133/349] Remove commented code --- vector/src/main/java/im/vector/app/core/di/FragmentModule.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 1f57031170..c68a35f4e5 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -993,9 +993,4 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment - - /*@Binds - @IntoMap - @FragmentKey(LocationLiveMapViewFragment::class) - fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment*/ } From b331521e933c9fa8faf2b0155dadc998eea65e0c Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 11:30:57 +0200 Subject: [PATCH 134/349] Improving code in Fragment --- .../live/map/LocationLiveMapViewFragment.kt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt index 23b78e0f0f..5020687ab9 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -26,7 +26,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMapOptions import com.mapbox.mapboxsdk.maps.SupportMapFragment import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.extensions.addFragment +import im.vector.app.core.extensions.addChildFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentLiveLocationMapBinding import im.vector.app.features.location.UrlMapProvider @@ -53,14 +53,7 @@ class LocationLiveMapViewFragment : VectorBaseFragment lifecycleScope.launchWhenCreated { @@ -69,6 +62,14 @@ class LocationLiveMapViewFragment : VectorBaseFragment Date: Mon, 23 May 2022 11:41:33 +0200 Subject: [PATCH 135/349] Making the layout file more generic --- .../location/live/map/LocationLiveMapViewFragment.kt | 10 +++++----- ..._location_map.xml => fragment_simple_container.xml} | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename vector/src/main/res/layout/{fragment_live_location_map.xml => fragment_simple_container.xml} (80%) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt index 5020687ab9..32b87727d8 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -28,7 +28,7 @@ import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addChildFragment import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.databinding.FragmentLiveLocationMapBinding +import im.vector.app.databinding.FragmentSimpleContainerBinding import im.vector.app.features.location.UrlMapProvider import javax.inject.Inject @@ -36,15 +36,15 @@ import javax.inject.Inject * Screen showing a map with all the current users sharing their live location in room. */ @AndroidEntryPoint -class LocationLiveMapViewFragment : VectorBaseFragment() { +class LocationLiveMapViewFragment : VectorBaseFragment() { @Inject lateinit var urlMapProvider: UrlMapProvider private val args: LocationLiveMapViewArgs by args() - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLiveLocationMapBinding { - return FragmentLiveLocationMapBinding.inflate(layoutInflater, container, false) + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSimpleContainerBinding { + return FragmentSimpleContainerBinding.inflate(layoutInflater, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -67,7 +67,7 @@ class LocationLiveMapViewFragment : VectorBaseFragment From a07c1b8afa9f54629b7267ab7dc3f0e05256a665 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 23 May 2022 13:46:53 +0100 Subject: [PATCH 136/349] Removes top bar back arrow --- .../vector/app/features/home/HomeDetailFragment.kt | 8 -------- .../src/main/res/layout/fragment_home_detail.xml | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 213c9fe193..4eedb528d1 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -145,10 +145,6 @@ class HomeDetailFragment @Inject constructor( updateTabVisibilitySafely(R.id.bottom_action_dial_pad, showDialPadTab) } - views.groupToolbarNavigateUp.setOnClickListener { - navigateBack() - } - viewModel.observeViewEvents { viewEvent -> when (viewEvent) { HomeDetailViewEvents.CallStarted -> handleCallStarted() @@ -307,13 +303,9 @@ class HomeDetailFragment @Inject constructor( private fun onSpaceChange(spaceSummary: RoomSummary?) { if (spaceSummary == null) { views.groupToolbarSpaceTitleView.isVisible = false - views.groupToolbarAvatarImageView.isVisible = true - views.groupToolbarNavigateUp.isVisible = false } else { views.groupToolbarSpaceTitleView.isVisible = true views.groupToolbarSpaceTitleView.text = spaceSummary.displayName - views.groupToolbarAvatarImageView.isVisible = false - views.groupToolbarNavigateUp.isVisible = true } } diff --git a/vector/src/main/res/layout/fragment_home_detail.xml b/vector/src/main/res/layout/fragment_home_detail.xml index 301abef4b8..e3db68434e 100644 --- a/vector/src/main/res/layout/fragment_home_detail.xml +++ b/vector/src/main/res/layout/fragment_home_detail.xml @@ -74,20 +74,6 @@ - - Date: Mon, 23 May 2022 12:02:43 +0200 Subject: [PATCH 137/349] Adding changelog entry --- changelog.d/6123.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6123.wip diff --git a/changelog.d/6123.wip b/changelog.d/6123.wip new file mode 100644 index 0000000000..680498280f --- /dev/null +++ b/changelog.d/6123.wip @@ -0,0 +1 @@ +[Live location sharing] Update entity in DB when a live is timed out From d76b93ced302ac92346bc0c4cafae04bcd55b594 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 14:26:23 +0200 Subject: [PATCH 138/349] Adding comment on isActive field --- .../model/livelocation/LiveLocationShareAggregatedSummary.kt | 3 +++ .../livelocation/LiveLocationShareAggregatedSummaryEntity.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt index 0b28d62f56..059fe21471 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationShareAggregatedSummary.kt @@ -22,6 +22,9 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati * Aggregation info concerning a live location share. */ data class LiveLocationShareAggregatedSummary( + /** + * Indicate whether the live is currently running. + */ val isActive: Boolean?, val endOfLiveTimestampMillis: Long?, val lastLocationDataContent: MessageBeaconLocationDataContent?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt index 4d0d2c5c64..e84337693f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt @@ -31,6 +31,9 @@ internal open class LiveLocationShareAggregatedSummaryEntity( var roomId: String = "", + /** + * Indicate whether the live is currently running. + */ var isActive: Boolean? = null, var endOfLiveTimestampMillis: Long? = null, From 47eb7173f0c773b1c0dd174e1faca83b997e9d31 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 15:15:45 +0200 Subject: [PATCH 139/349] Creation of a worker to deactivate a live after timeout --- .../sdk/internal/session/SessionComponent.kt | 3 + .../DeactivateLiveLocationShareWorker.kt | 89 +++++++++++++++++++ .../internal/worker/MatrixWorkerFactory.kt | 7 +- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt index 050480e6c9..1e3566f49e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt @@ -46,6 +46,7 @@ import org.matrix.android.sdk.internal.session.profile.ProfileModule import org.matrix.android.sdk.internal.session.pushers.AddPusherWorker import org.matrix.android.sdk.internal.session.pushers.PushersModule import org.matrix.android.sdk.internal.session.room.RoomModule +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DeactivateLiveLocationShareWorker import org.matrix.android.sdk.internal.session.room.send.MultipleEventSendingDispatcherWorker import org.matrix.android.sdk.internal.session.room.send.RedactEventWorker import org.matrix.android.sdk.internal.session.room.send.SendEventWorker @@ -131,6 +132,8 @@ internal interface SessionComponent { fun inject(worker: UpdateTrustWorker) + fun inject(worker: DeactivateLiveLocationShareWorker) + @Component.Factory interface Factory { fun create( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt new file mode 100644 index 0000000000..14fc1566d8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.livelocation + +import android.content.Context +import androidx.work.WorkerParameters +import com.squareup.moshi.JsonClass +import io.realm.RealmConfiguration +import org.matrix.android.sdk.internal.SessionManager +import org.matrix.android.sdk.internal.database.awaitTransaction +import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity +import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.session.SessionComponent +import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker +import org.matrix.android.sdk.internal.worker.SessionWorkerParams +import timber.log.Timber +import javax.inject.Inject + +/** + * Worker dedicated to update live location summary data so that it is considered as deactivated. + * For the context: it is needed since a live location share should be deactivated after a certain timeout. + */ +internal class DeactivateLiveLocationShareWorker(context: Context, params: WorkerParameters, sessionManager: SessionManager) : + SessionSafeCoroutineWorker( + context, + params, + sessionManager, + Params::class.java + ) { + + @JsonClass(generateAdapter = true) + internal data class Params( + override val sessionId: String, + override val lastFailureMessage: String? = null, + val eventId: String, + val roomId: String + ) : SessionWorkerParams + + @SessionDatabase + @Inject lateinit var realmConfiguration: RealmConfiguration + + override fun injectWith(injector: SessionComponent) { + injector.inject(this) + } + + override suspend fun doSafeWork(params: Params): Result { + return runCatching { + deactivateLiveLocationShare(params) + }.fold( + onSuccess = { + Result.success() + }, + onFailure = { + Timber.e("failed to deactivate live, eventId: ${params.eventId}, roomId: ${params.roomId}") + Result.failure() + } + ) + } + + private suspend fun deactivateLiveLocationShare(params: Params) { + awaitTransaction(realmConfiguration) { realm -> + val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.getOrCreate( + realm = realm, + roomId = params.roomId, + eventId = params.eventId + ) + aggregatedSummary.isActive = false + } + } + + override fun buildErrorParams(params: Params, message: String): Params { + return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt index 95b3662c67..a8ef3e0748 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/MatrixWorkerFactory.kt @@ -27,6 +27,7 @@ import org.matrix.android.sdk.internal.di.MatrixScope import org.matrix.android.sdk.internal.session.content.UploadContentWorker import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.pushers.AddPusherWorker +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DeactivateLiveLocationShareWorker import org.matrix.android.sdk.internal.session.room.send.MultipleEventSendingDispatcherWorker import org.matrix.android.sdk.internal.session.room.send.RedactEventWorker import org.matrix.android.sdk.internal.session.room.send.SendEventWorker @@ -64,9 +65,11 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage SyncWorker(appContext, workerParameters, sessionManager) UpdateTrustWorker::class.java.name -> UpdateTrustWorker(appContext, workerParameters, sessionManager) - UploadContentWorker::class.java.name -> + UploadContentWorker::class.java.name -> UploadContentWorker(appContext, workerParameters, sessionManager) - else -> { + DeactivateLiveLocationShareWorker::class.java.name -> + DeactivateLiveLocationShareWorker(appContext, workerParameters, sessionManager) + else -> { Timber.w("No worker defined on MatrixWorkerFactory for $workerClassName will delegate to default.") // Return null to delegate to the default WorkerFactory. null From 683a9cdfff319d16cf4d5a347b87a6f847005728 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 15:53:25 +0200 Subject: [PATCH 140/349] Schedule work during aggregation --- .../DeactivateLiveLocationShareWorker.kt | 6 +++ .../LiveLocationAggregationProcessor.kt | 50 +++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index 14fc1566d8..6461b90435 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -86,4 +86,10 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke override fun buildErrorParams(params: Params, message: String): Params { return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) } + + companion object { + private const val WORK_NAME_PREFIX = "DeactivateLiveLocationWork-" + + fun getWorkName(eventId: String, roomId: String) = "${WORK_NAME_PREFIX}$eventId-$roomId" + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index 76b7a4ec8e..74e8ce8be2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.aggregation.livelocation +import androidx.work.ExistingWorkPolicy import io.realm.Realm import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.session.events.model.Event @@ -26,17 +27,27 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.di.SessionId +import org.matrix.android.sdk.internal.di.WorkManagerProvider +import org.matrix.android.sdk.internal.util.time.Clock +import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber +import java.util.concurrent.TimeUnit import javax.inject.Inject -internal class LiveLocationAggregationProcessor @Inject constructor() { +internal class LiveLocationAggregationProcessor @Inject constructor( + @SessionId private val sessionId: String, + private val workManagerProvider: WorkManagerProvider, + private val clock: Clock, +) { fun handleBeaconInfo(realm: Realm, event: Event, content: MessageBeaconInfoContent, roomId: String, isLocalEcho: Boolean) { if (event.senderId.isNullOrEmpty() || isLocalEcho) { return } - val targetEventId = if (content.isLive.orTrue()) { + val isLive = content.isLive.orTrue() + val targetEventId = if (isLive) { event.eventId } else { // when live is set to false, we use the id of the event that should have been replaced @@ -56,8 +67,39 @@ internal class LiveLocationAggregationProcessor @Inject constructor() { Timber.d("updating summary of id=$targetEventId with isLive=${content.isLive}") - aggregatedSummary.endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } - aggregatedSummary.isActive = content.isLive + val endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } + aggregatedSummary.endOfLiveTimestampMillis = endOfLiveTimestampMillis + aggregatedSummary.isActive = isLive + + if (isLive) { + scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis) + } else { + cancelDeactivationAfterTimeout(targetEventId, roomId) + } + } + + private fun scheduleDeactivationAfterTimeout(eventId: String, roomId: String, endOfLiveTimestampMillis: Long?) { + endOfLiveTimestampMillis?.let { endOfLiveMillis -> + val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) + val workData = WorkerParamsFactory.toData(workParams) + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + val workDelayMillis = (endOfLiveMillis - clock.epochMillis()).coerceAtLeast(0) + val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() + .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) + .setInputData(workData) + .build() + + workManagerProvider.workManager.enqueueUniqueWork( + workName, + ExistingWorkPolicy.KEEP, + workRequest + ) + } + } + + private fun cancelDeactivationAfterTimeout(eventId: String, roomId: String) { + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + workManagerProvider.workManager.cancelUniqueWork(workName) } fun handleBeaconLocationData( From b05fc763aec15fc142e6727c01cea09244c96177 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 23 May 2022 16:06:48 +0200 Subject: [PATCH 141/349] Rely only on isActive field on UI side --- .../factory/LiveLocationShareMessageItemFactory.kt | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt index 912702aaed..3c7b6c32e1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt @@ -33,7 +33,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocation import im.vector.app.features.location.INITIAL_MAP_ZOOM_IN_TIMELINE import im.vector.app.features.location.UrlMapProvider import im.vector.app.features.location.toLocationData -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.threeten.bp.LocalDateTime @@ -129,7 +128,7 @@ class LiveLocationShareMessageItemFactory @Inject constructor( private fun getViewState(liveLocationShareSummaryData: LiveLocationShareSummaryData?): LiveLocationShareViewState { return when { liveLocationShareSummaryData?.isActive == null -> LiveLocationShareViewState.Unkwown - liveLocationShareSummaryData.isActive.not() || isLiveTimedOut(liveLocationShareSummaryData) -> LiveLocationShareViewState.Inactive + liveLocationShareSummaryData.isActive.not() -> LiveLocationShareViewState.Inactive liveLocationShareSummaryData.isActive && liveLocationShareSummaryData.lastGeoUri.isNullOrEmpty() -> LiveLocationShareViewState.Loading else -> LiveLocationShareViewState.Running( @@ -139,16 +138,6 @@ class LiveLocationShareMessageItemFactory @Inject constructor( }.also { viewState -> Timber.d("computed viewState: $viewState") } } - private fun isLiveTimedOut(liveLocationShareSummaryData: LiveLocationShareSummaryData): Boolean { - return getEndOfLiveDateTime(liveLocationShareSummaryData) - ?.let { endOfLive -> - // this will only cover users with different timezones but not users with manually time set - val now = LocalDateTime.now() - now.isAfter(endOfLive) - } - .orFalse() - } - private fun getEndOfLiveDateTime(liveLocationShareSummaryData: LiveLocationShareSummaryData): LocalDateTime? { return liveLocationShareSummaryData.endOfLiveTimestampMillis?.let { DateProvider.toLocalDateTime(timestamp = it) } } From b131848b722c7df18d59f4c71e1d7cdedfd07f3b Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2022 14:12:49 +1200 Subject: [PATCH 142/349] Fix grammar in strings in strings.xml `room_list_people_empty_body` and `room_list_rooms_empty_body` --- vector/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 63d4730dc5..24e984a6bc 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1584,9 +1584,9 @@ You’re all caught up! You have no more unread messages Conversations - Your direct message conversations will be displayed here. Tap the + bottom right to start some. + Your direct message conversations will be displayed here. Tap the + at the bottom right to start some. Rooms - Your rooms will be displayed here. Tap the + bottom right to find existing ones or start some of your own. + Your rooms will be displayed here. Tap the + at the bottom right to find existing ones or start some of your own. Reactions Add Reaction From 3b1a7f93cbad810000b4a13d65dc94301989c7ae Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2022 14:40:13 +1200 Subject: [PATCH 143/349] Create 6132.misc --- changelog.d/6132.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6132.misc diff --git a/changelog.d/6132.misc b/changelog.d/6132.misc new file mode 100644 index 0000000000..4bcfb224ef --- /dev/null +++ b/changelog.d/6132.misc @@ -0,0 +1 @@ +Fixed grammar errors in /vector/src/main/res/values/strings.xml From bec72264cda134bd99502b760c83581cd6b18aa4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 24 May 2022 09:34:37 +0100 Subject: [PATCH 144/349] excluding the gms play-service-location optional transistive dependency for the fdroid variant - fixes fdroid being unable to compile the project due to a non foss dependency --- changelog.d/6100.misc | 1 + dependencies.gradle | 4 ++++ vector/build.gradle | 11 ++++++++--- 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 changelog.d/6100.misc diff --git a/changelog.d/6100.misc b/changelog.d/6100.misc new file mode 100644 index 0000000000..2fb5ecf34d --- /dev/null +++ b/changelog.d/6100.misc @@ -0,0 +1 @@ +Excludes transitive optional non FOSS google location dependency from fdroid builds diff --git a/dependencies.gradle b/dependencies.gradle index 47dc8ddc03..a0919371eb 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -107,6 +107,10 @@ ext.libs = [ 'mavericks' : "com.airbnb.android:mavericks:$mavericks", 'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks" ], + maplibre : [ + 'androidSdk' : "org.maplibre.gl:android-sdk:9.5.2", + 'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:1.0.0" + ], mockk : [ 'mockk' : "io.mockk:mockk:$mockk", 'mockkAndroid' : "io.mockk:mockk-android:$mockk" diff --git a/vector/build.gradle b/vector/build.gradle index 4ae6527e0b..51dfc2f962 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -507,9 +507,14 @@ dependencies { implementation 'commons-codec:commons-codec:1.15' // MapTiler - implementation 'org.maplibre.gl:android-sdk:9.5.2' - implementation 'org.maplibre.gl:android-plugin-annotation-v9:1.0.0' - + fdroidImplementation(libs.maplibre.androidSdk) { + exclude group: 'com.google.android.gms', module: 'play-services-location' + } + fdroidImplementation(libs.maplibre.pluginAnnotation) { + exclude group: 'com.google.android.gms', module: 'play-services-location' + } + gplayImplementation libs.maplibre.androidSdk + gplayImplementation libs.maplibre.pluginAnnotation // TESTS testImplementation libs.tests.junit From 6c21a6b48daa653f361a4f657dd6fa041c8c82a6 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 24 May 2022 15:26:24 +0200 Subject: [PATCH 145/349] Separates some method parameters --- .../api/session/crypto/keysbackup/KeysBackupService.kt | 3 ++- .../android/sdk/internal/crypto/store/IMXCryptoStore.kt | 8 ++++++-- .../crypto/verification/DefaultVerificationTransaction.kt | 3 ++- .../sdk/internal/session/profile/BindThreePidsTask.kt | 3 +-- .../im/vector/app/features/login2/LoginWebFragment2.kt | 3 ++- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index a0b1604e86..5947c1dca7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -200,7 +200,8 @@ interface KeysBackupService { */ fun restoreKeysWithRecoveryKey( keysVersionResult: KeysVersionResult, - recoveryKey: String, roomId: String?, + recoveryKey: String, + roomId: String?, sessionId: String?, stepProgressListener: StepProgressListener?, callback: MatrixCallback diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 72014ff3bb..b18de34329 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -483,8 +483,12 @@ internal interface IMXCryptoStore { fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? fun markedSessionAsShared( - roomId: String?, sessionId: String, userId: String, deviceId: String, - deviceIdentityKey: String, chainIndex: Int + roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String, + chainIndex: Int ) /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt index b683c8905f..9d19fd137e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt @@ -59,7 +59,8 @@ internal abstract class DefaultVerificationTransaction( protected fun trust( canTrustOtherUserMasterKey: Boolean, toVerifyDeviceIds: List, - eventuallyMarkMyMasterKeyAsTrusted: Boolean, autoDone: Boolean = true + eventuallyMarkMyMasterKeyAsTrusted: Boolean, + autoDone: Boolean = true ) { Timber.d("## Verification: trust ($otherUserId,$otherDeviceId) , verifiedDevices:$toVerifyDeviceIds") Timber.d("## Verification: trust Mark myMSK trusted $eventuallyMarkMyMasterKeyAsTrusted") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt index 71e9743c6a..5e892b32c3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidsTask.kt @@ -36,8 +36,7 @@ internal abstract class BindThreePidsTask : Task internal class DefaultBindThreePidsTask @Inject constructor( private val profileAPI: ProfileAPI, private val identityStore: IdentityStore, - @AuthenticatedIdentity - private val accessTokenProvider: AccessTokenProvider, + @AuthenticatedIdentity private val accessTokenProvider: AccessTokenProvider, private val globalErrorReceiver: GlobalErrorReceiver ) : BindThreePidsTask() { override suspend fun execute(params: Params) { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index bc79ef8bd8..e633a110ef 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -125,7 +125,8 @@ class LoginWebFragment2 @Inject constructor( views.loginWebWebView.webViewClient = object : WebViewClient() { override fun onReceivedSslError( - view: WebView, handler: SslErrorHandler, + view: WebView, + handler: SslErrorHandler, error: SslError ) { MaterialAlertDialogBuilder(requireActivity()) From c3209d70490ebfcbd14ed1e6e433573e35e9feda Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 24 May 2022 15:31:20 +0200 Subject: [PATCH 146/349] Manually fixes more formatting issues --- .../sdk/internal/crypto/ExportEncryptionTest.kt | 16 ++++++++-------- .../store/db/query/SharedSessionQueries.kt | 3 ++- .../VerificationTransportRoomMessage.kt | 8 ++++++-- .../database/helper/ThreadEventsHelper.kt | 3 ++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ExportEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ExportEncryptionTest.kt index 65ba33cb02..2f2d54b7e3 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ExportEncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ExportEncryptionTest.kt @@ -83,8 +83,8 @@ class ExportEncryptionTest { @Test fun checkExportDecrypt1() { val password = "password" - val input = - "-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" + "cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----" + val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXNhbHRzYWx0c2FsdHNhbHSIiIiIiIiIiIiIiIiIiIiIAAAACmIRUW2OjZ3L2l6j9h0lHlV3M2dx\n" + + "cissyYBxjsfsAndErh065A8=\n-----END MEGOLM SESSION DATA-----" val expectedString = "plain" var decodedString: String? = null @@ -104,8 +104,8 @@ class ExportEncryptionTest { @Test fun checkExportDecrypt2() { val password = "betterpassword" - val input = - "-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" + "KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----" + val input = "-----BEGIN MEGOLM SESSION DATA-----\nAW1vcmVzYWx0bW9yZXNhbHT//////////wAAAAAAAAAAAAAD6KyBpe1Niv5M5NPm4ZATsJo5nghk\n" + + "KYu63a0YQ5DRhUWEKk7CcMkrKnAUiZny\n-----END MEGOLM SESSION DATA-----" val expectedString = "Hello, World" var decodedString: String? = null @@ -125,8 +125,8 @@ class ExportEncryptionTest { @Test fun checkExportDecrypt3() { val password = "SWORDFISH" - val input = - "-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" + "MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----" + val input = "-----BEGIN MEGOLM SESSION DATA-----\nAXllc3NhbHR5Z29vZG5lc3P//////////wAAAAAAAAAAAAAD6OIW+Je7gwvjd4kYrb+49gKCfExw\n" + + "MgJBMD4mrhLkmgAngwR1pHjbWXaoGybtiAYr0moQ93GrBQsCzPbvl82rZhaXO3iH5uHo/RCEpOqp\nPgg29363BGR+/Ripq/VCLKGNbw==\n-----END MEGOLM SESSION DATA-----" val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically" var decodedString: String? = null @@ -205,8 +205,8 @@ class ExportEncryptionTest { @Test fun checkExportEncrypt4() { - val password = - "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + val password = "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" + + "passwordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpasswordpassword" val expectedString = "alphanumericallyalphanumericallyalphanumericallyalphanumerically" var decodedString: String? = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt index 97fab9174d..85dd50c88e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt @@ -51,7 +51,8 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se } internal fun SharedSessionEntity.Companion.create( - realm: Realm, roomId: String?, + realm: Realm, + roomId: String?, sessionId: String, userId: String, deviceId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt index 350c5e8cd1..f38a604890 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt @@ -164,8 +164,12 @@ internal class VerificationTransportRoomMessage( } } - override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceIds: List, code: CancelCode) = - cancelTransaction(transactionId, otherUserId, null, code) + override fun cancelTransaction( + transactionId: String, + otherUserId: String, + otherUserDeviceIds: List, + code: CancelCode + ) = cancelTransaction(transactionId, otherUserId, null, code) override fun done( transactionId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt index 5b2e27c24a..dfac7f6708 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt @@ -47,7 +47,8 @@ private typealias Summary = Pair? */ internal fun Map.updateThreadSummaryIfNeeded( roomId: String, - realm: Realm, currentUserId: String, + realm: Realm, + currentUserId: String, chunkEntity: ChunkEntity? = null, shouldUpdateNotifications: Boolean = true ) { From f95853a7b3c103854f6c29f65218f3ed0ead78df Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 24 May 2022 16:28:56 +0200 Subject: [PATCH 147/349] Prevent widget web view from reloading on screen / orientation change (PSF-1034) Signed-off-by: Johannes Marbach --- vector/src/main/AndroidManifest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index fc78ce90a3..8c2e25bc7e 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -306,7 +306,9 @@ android:supportsPictureInPicture="true" /> - + + From 7913a42664e1a3c6c658aa74bce1a682530a1b32 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 24 May 2022 16:36:26 +0200 Subject: [PATCH 148/349] Add changelog file --- changelog.d/6140.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6140.bugfix diff --git a/changelog.d/6140.bugfix b/changelog.d/6140.bugfix new file mode 100644 index 0000000000..247e69f837 --- /dev/null +++ b/changelog.d/6140.bugfix @@ -0,0 +1 @@ +Prevent widget web view from reloading on screen / orientation change From d4af2a7a87b63da9f62954a9843d566465aaa92a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 May 2022 15:26:52 +0000 Subject: [PATCH 149/349] Bump vanniktechEmoji from 0.9.0 to 0.13.0 Bumps `vanniktechEmoji` from 0.9.0 to 0.13.0. Updates `emoji-material` from 0.9.0 to 0.13.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.13.0) Updates `emoji-google` from 0.9.0 to 0.13.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.13.0) --- updated-dependencies: - dependency-name: com.vanniktech:emoji-material dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.vanniktech:emoji-google dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index af27b913a9..ed42e67b99 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -23,7 +23,7 @@ def mavericks = "2.6.1" def glide = "4.13.2" def bigImageViewer = "1.8.1" def jjwt = "0.11.5" -def vanniktechEmoji = "0.12.0" +def vanniktechEmoji = "0.13.0" // Testing def mockk = "1.12.4" From 5766414d791c0ed0d3945f168cb208715caca000 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Tue, 24 May 2022 16:36:14 +0100 Subject: [PATCH 150/349] Downgrade gradle from 7.2.0 to 7.1.3 --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index af27b913a9..88d53f5d2f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,7 +7,7 @@ ext.versions = [ 'targetCompat' : JavaVersion.VERSION_11, ] -def gradle = "7.2.0" +def gradle = "7.1.3" // Ref: https://kotlinlang.org/releases.html def kotlin = "1.6.21" def kotlinCoroutines = "1.6.1" From 20422a5451e3f925e9c3b6a5823f16a632474b5d Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Tue, 24 May 2022 16:40:03 +0100 Subject: [PATCH 151/349] towncrier --- changelog.d/6141.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6141.misc diff --git a/changelog.d/6141.misc b/changelog.d/6141.misc new file mode 100644 index 0000000000..2f0a91b451 --- /dev/null +++ b/changelog.d/6141.misc @@ -0,0 +1 @@ +Downgrade gradle from 7.2.0 to 7.1.3 From 5faa2ff205b4e632ca751a215144fc87b8ab98ce Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Tue, 24 May 2022 16:53:17 +0100 Subject: [PATCH 152/349] Add comment linking to an issue --- dependencies.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dependencies.gradle b/dependencies.gradle index 88d53f5d2f..3839ecf60e 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,6 +7,9 @@ ext.versions = [ '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" // Ref: https://kotlinlang.org/releases.html def kotlin = "1.6.21" From d0628129f5704505890495cf4c56d2b95aba8fa2 Mon Sep 17 00:00:00 2001 From: Jean-Luc KABORE-TURQUIN Date: Wed, 25 May 2022 07:14:49 +0000 Subject: [PATCH 153/349] Translated using Weblate (French) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- vector/src/main/res/values-fr/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index fc41b217c1..c7b1b8c797 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2454,4 +2454,5 @@ \nPour nous y préparer, nous avons besoin de faire certains changements : les fils créés avant maintenant seront affichés comme des réponses classiques. \n \nCette transition sera unique, maintenant que les fils de discussions ont intégré la spécification de Matrix. - + Partage d\'écran en cours + \ No newline at end of file From 71706bc6a65d54ebca42ffb935eabd739a1f0660 Mon Sep 17 00:00:00 2001 From: Glandos Date: Wed, 25 May 2022 07:14:30 +0000 Subject: [PATCH 154/349] Translated using Weblate (French) Currently translated at 100.0% (2225 of 2225 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- vector/src/main/res/values-fr/strings.xml | 51 ++++++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index c7b1b8c797..4cf1b89b84 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -407,9 +407,7 @@ Paramètres utilisateur %1$s @ %2$s Vérifiez votre courriel et cliquez sur le lien qu’il contient. Une fois ceci fait, cliquez sur continuer. - Afficher tous les messages de %s \? -\n -\nVeuillez noter que cette action redémarrera l’application et pourra prendre un certain temps. + Afficher tous les messages de %s \? Qui peut lire l’historique \? Uniquement les membres (à partir de l’activation de cette option) Uniquement les membres (depuis leur invitation) @@ -1683,7 +1681,7 @@ Adresses électroniques Aucun numéro de téléphone n’a été ajouté à votre compte Filtrer les utilisateurs exclus - Ne plus ignorer cet utilisateur aura pour effet de ré-afficher ses messages. + Ne plus ignorer cet utilisateur affichera à nouveau ses messages. expulser un utilisateur le supprimera de ce salon. \n \nPour l’empêcher de revenir, vous devez plutôt le bannir. @@ -2253,7 +2251,7 @@ L’expulsion des utilisateurs va les supprimer de cet espace \n \nPour les empêcher de revenir, vous devriez les exclure. - Indisponible + Absent Hors ligne En ligne Choisir un serveur d’accueil @@ -2334,7 +2332,7 @@ Activer les mathématiques LaTeX Votre système enverra automatiquement des informations dès qu’une erreur de déchiffrement de message se présente Signalement automatique des erreurs de déchiffrement. - Outrepasser la couleur du pseudo + Outrepasser la couleur du pseudonyme J’ai déjà un compte Messagerie sécurisée. Vous êtes aux commandes. @@ -2455,4 +2453,45 @@ \n \nCette transition sera unique, maintenant que les fils de discussions ont intégré la spécification de Matrix. Partage d\'écran en cours + Partage d’écran pour ${app_name} + Chargement de la position en direct… + 8 heures + 1 heure + 15 minutes + Partager votre position en direct pendant + (%1$s) + %1$s (%2$s) + Impossible de lire %1$s + Pause %1$s + Lire %1$s + %1$d minutes %2$d secondes + %1$s, %2$s, %3$s + Afficher les informations des profils les plus récentes (avatar et nom d’affichage) pour tous les messages. + Afficher les informations utilisateurs les plus récentes + Occupé + On partagé leur position en direct + ${app_name} est parfaite pour le bureau. Les sociétés aux plus gros besoins de sécurité lui font confiance. + BÊTA + Les fils de discussion sont en cours de développement avec des fonctionnalités nouvelles et excitantes à venir, telles que des notifications améliorées. Nous adorerions avoir vos remarques ! + Remarques sur les fils de discussion Bêta + Emvoyer des remarques + BÊTA + La sauvegarde a une signature valide de cet utilisateur. + Si active, vous apparaîtrez toujours hors-ligne aux autres utilisateurs, même lorsque vous utilisez l’application. + Mode hors-ligne + Présence + Votre serveur d\'accueil ne prend pas actuellement en charge les fils de discussions, cette fonctionnalité peut donc ne pas être fiable. Certains messages dans les fils de discussions peuvent ne pas être disponibles de manière fiable. %sVoulez-vous activer les fils de discussion malgré tout \? + Fils de discussion Bêta + Les fils de discussion vous permettent de recentrer vos conversations et de les rendre facile à suivre. %sActiver les fils de discussion rechargera l’application. Cela peut prendre du temps pour certains comptes. + Fils de discussion Bêta + – Certains utilisateurs ne sont plus ignorés + Arrêter le partage d’écran + Partager l’écran + En savoir plus + Essayer + ${app_name} a besoin d’effacer le cache pour la mise-à-jour, pour la raison suivante : +\n%s +\n +\nCette action va redémarrer l’application et pourra prendre du temps. + Requête de synchronisation initiale \ No newline at end of file From b081429725637a74d0daa6df2f48602b96a33882 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 10:59:08 +0200 Subject: [PATCH 155/349] Replace getOrCreate() by get() in worker --- .../LiveLocationShareAggregatedSummaryEntityQuery.kt | 8 ++++++++ .../livelocation/DeactivateLiveLocationShareWorker.kt | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt index 2e2e939fa2..816b5f4392 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt @@ -55,3 +55,11 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.getOrCreate( return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst() ?: LiveLocationShareAggregatedSummaryEntity.create(realm, roomId, eventId) } + +internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get( + realm: Realm, + roomId: String, + eventId: String, +): LiveLocationShareAggregatedSummaryEntity? { + return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index 6461b90435..a437975668 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -23,7 +23,7 @@ import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity -import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.database.query.get import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker @@ -74,12 +74,12 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke private suspend fun deactivateLiveLocationShare(params: Params) { awaitTransaction(realmConfiguration) { realm -> - val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.getOrCreate( + val aggregatedSummary = LiveLocationShareAggregatedSummaryEntity.get( realm = realm, roomId = params.roomId, eventId = params.eventId ) - aggregatedSummary.isActive = false + aggregatedSummary?.isActive = false } } From cfdc18d421df0e311b299cf267d2f040e96561ea Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:05:28 +0200 Subject: [PATCH 156/349] Improve code readability in aggregation processor --- .../LiveLocationAggregationProcessor.kt | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index 74e8ce8be2..b9529143a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -79,22 +79,22 @@ internal class LiveLocationAggregationProcessor @Inject constructor( } private fun scheduleDeactivationAfterTimeout(eventId: String, roomId: String, endOfLiveTimestampMillis: Long?) { - endOfLiveTimestampMillis?.let { endOfLiveMillis -> - val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) - val workData = WorkerParamsFactory.toData(workParams) - val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) - val workDelayMillis = (endOfLiveMillis - clock.epochMillis()).coerceAtLeast(0) - val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() - .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) - .setInputData(workData) - .build() + endOfLiveTimestampMillis ?: return - workManagerProvider.workManager.enqueueUniqueWork( - workName, - ExistingWorkPolicy.KEEP, - workRequest - ) - } + val workParams = DeactivateLiveLocationShareWorker.Params(sessionId = sessionId, eventId = eventId, roomId = roomId) + val workData = WorkerParamsFactory.toData(workParams) + val workName = DeactivateLiveLocationShareWorker.getWorkName(eventId = eventId, roomId = roomId) + val workDelayMillis = (endOfLiveTimestampMillis - clock.epochMillis()).coerceAtLeast(0) + val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() + .setInitialDelay(workDelayMillis, TimeUnit.MILLISECONDS) + .setInputData(workData) + .build() + + workManagerProvider.workManager.enqueueUniqueWork( + workName, + ExistingWorkPolicy.KEEP, + workRequest + ) } private fun cancelDeactivationAfterTimeout(eventId: String, roomId: String) { From 8864a3cf2c460964f4e63f74c4c6e1a6ea4f1fb2 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:06:02 +0200 Subject: [PATCH 157/349] Using replace instead of keep strategy for the worker --- .../livelocation/LiveLocationAggregationProcessor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index b9529143a6..42dfc7ba9f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -92,7 +92,7 @@ internal class LiveLocationAggregationProcessor @Inject constructor( workManagerProvider.workManager.enqueueUniqueWork( workName, - ExistingWorkPolicy.KEEP, + ExistingWorkPolicy.REPLACE, workRequest ) } From 791d4fb1e87e517d9bbde7eb3bff6877ff72b3e3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 25 May 2022 11:10:54 +0200 Subject: [PATCH 158/349] Improve computation of the work name to limit its length --- .../livelocation/DeactivateLiveLocationShareWorker.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt index a437975668..2b83c8028b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DeactivateLiveLocationShareWorker.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import io.realm.RealmConfiguration +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity @@ -88,8 +89,9 @@ internal class DeactivateLiveLocationShareWorker(context: Context, params: Worke } companion object { - private const val WORK_NAME_PREFIX = "DeactivateLiveLocationWork-" - - fun getWorkName(eventId: String, roomId: String) = "${WORK_NAME_PREFIX}$eventId-$roomId" + fun getWorkName(eventId: String, roomId: String): String { + val hash = "$eventId$roomId".md5() + return "DeactivateLiveLocationWork-$hash" + } } } From 34e97112a491cdeab5b03a96b134a00e494d104b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 29 Apr 2022 11:55:43 +0100 Subject: [PATCH 159/349] adding feature flag and redirecting the sign in flow - temporarily to the combined register fragment --- .../features/debug/features/DebugFeaturesStateFactory.kt | 5 +++++ .../app/features/debug/features/DebugVectorFeatures.kt | 4 ++++ .../src/main/java/im/vector/app/features/VectorFeatures.kt | 2 ++ .../vector/app/features/onboarding/OnboardingViewEvents.kt | 1 + .../vector/app/features/onboarding/OnboardingViewModel.kt | 4 +++- .../app/features/onboarding/ftueauth/FtueAuthVariant.kt | 7 ++++++- 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt index 00a073f832..aa4df5e308 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt @@ -60,6 +60,11 @@ class DebugFeaturesStateFactory @Inject constructor( key = DebugFeatureKeys.onboardingCombinedRegister, factory = VectorFeatures::isOnboardingCombinedRegisterEnabled ), + createBooleanFeature( + label = "FTUE Combined login", + key = DebugFeatureKeys.onboardingCombinedLogin, + factory = VectorFeatures::isOnboardingCombinedLoginEnabled + ), ) ) } diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt index 1bc37ff97e..f36b1a804a 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt @@ -57,6 +57,9 @@ class DebugVectorFeatures( override fun isOnboardingCombinedRegisterEnabled(): Boolean = read(DebugFeatureKeys.onboardingCombinedRegister) ?: vectorFeatures.isOnboardingCombinedRegisterEnabled() + override fun isOnboardingCombinedLoginEnabled(): Boolean = read(DebugFeatureKeys.onboardingCombinedLogin) + ?: vectorFeatures.isOnboardingCombinedLoginEnabled() + override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing) ?: vectorFeatures.isScreenSharingEnabled() @@ -113,6 +116,7 @@ object DebugFeatureKeys { val onboardingUseCase = booleanPreferencesKey("onboarding-splash-carousel") val onboardingPersonalize = booleanPreferencesKey("onboarding-personalize") val onboardingCombinedRegister = booleanPreferencesKey("onboarding-combined-register") + val onboardingCombinedLogin = booleanPreferencesKey("onboarding-combined-login") val liveLocationSharing = booleanPreferencesKey("live-location-sharing") val screenSharing = booleanPreferencesKey("screen-sharing") } diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt index e3fded2824..6a7a0865de 100644 --- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt +++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt @@ -26,6 +26,7 @@ interface VectorFeatures { fun isOnboardingUseCaseEnabled(): Boolean fun isOnboardingPersonalizeEnabled(): Boolean fun isOnboardingCombinedRegisterEnabled(): Boolean + fun isOnboardingCombinedLoginEnabled(): Boolean fun isScreenSharingEnabled(): Boolean enum class OnboardingVariant { @@ -42,5 +43,6 @@ class DefaultVectorFeatures : VectorFeatures { override fun isOnboardingUseCaseEnabled() = true override fun isOnboardingPersonalizeEnabled() = false override fun isOnboardingCombinedRegisterEnabled() = false + override fun isOnboardingCombinedLoginEnabled() = false override fun isScreenSharingEnabled(): Boolean = true } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt index 6ffece4ab6..5dbcd162f3 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt @@ -37,6 +37,7 @@ sealed class OnboardingViewEvents : VectorViewEvents { object OpenUseCaseSelection : OnboardingViewEvents() object OpenServerSelection : OnboardingViewEvents() object OpenCombinedRegister : OnboardingViewEvents() + object OpenCombinedLogin : OnboardingViewEvents() object EditServerSelection : OnboardingViewEvents() data class OnServerSelectionDone(val serverType: ServerType) : OnboardingViewEvents() object OnLoginFlowRetrieved : OnboardingViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index cf730a0266..4ee26c2976 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -194,7 +194,9 @@ class OnboardingViewModel @AssistedInject constructor( } else { OnboardingViewEvents.OpenServerSelection } - OnboardingFlow.SignIn, + OnboardingFlow.SignIn -> if (vectorFeatures.isOnboardingCombinedRegisterEnabled()) { + OnboardingViewEvents.OpenCombinedLogin + } else OnboardingViewEvents.OpenServerSelection OnboardingFlow.SignInSignUp -> OnboardingViewEvents.OpenServerSelection } _viewEvents.post(nextOnboardingStep) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 8430b483d2..d7b8171225 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -227,10 +227,15 @@ class FtueAuthVariant( option = commonOption ) } - OnboardingViewEvents.OnHomeserverEdited -> activity.popBackstack() + OnboardingViewEvents.OnHomeserverEdited -> activity.popBackstack() + OnboardingViewEvents.OpenCombinedLogin -> onStartCombinedLogin() } } + private fun onStartCombinedLogin() { + addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java) + } + private fun onRegistrationFlow(viewEvents: OnboardingViewEvents.RegistrationFlowResult) { when { registrationShouldFallback(viewEvents) -> displayFallbackWebDialog() From 4b6f74364d68e09265eb1ecb4d6665ba6d75a230 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 5 May 2022 14:01:18 +0100 Subject: [PATCH 160/349] adding dedicated login action --- .../features/onboarding/OnboardingAction.kt | 1 + .../onboarding/OnboardingViewModel.kt | 28 +- .../ftueauth/FtueAuthCombinedLoginFragment.kt | 198 +++++++++++++ .../onboarding/ftueauth/FtueAuthVariant.kt | 2 +- .../layout/fragment_ftue_combined_login.xml | 275 ++++++++++++++++++ vector/src/main/res/values/donottranslate.xml | 2 + 6 files changed, 493 insertions(+), 13 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt create mode 100644 vector/src/main/res/layout/fragment_ftue_combined_login.xml diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt index 9f7dce56ea..d5b12a8071 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt @@ -49,6 +49,7 @@ sealed interface OnboardingAction : VectorViewModelAction { // Login or Register, depending on the signMode data class LoginOrRegister(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction data class Register(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction + data class Login(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction object StopEmailValidationCheck : OnboardingAction data class PostRegisterAction(val registerAction: RegisterAction) : OnboardingAction diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 4ee26c2976..1ca2556c71 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -141,6 +141,7 @@ class OnboardingViewModel @AssistedInject constructor( is OnboardingAction.HomeServerChange -> withAction(action) { handleHomeserverChange(action) } is OnboardingAction.LoginOrRegister -> handleLoginOrRegister(action).also { lastAction = action } is OnboardingAction.Register -> handleRegisterWith(action).also { lastAction = action } + is OnboardingAction.Login -> handleLogin(action).also { lastAction = action } is OnboardingAction.LoginWithToken -> handleLoginWithToken(action) is OnboardingAction.WebLoginSuccess -> handleWebLoginSuccess(action) is OnboardingAction.ResetPassword -> handleResetPassword(action) @@ -188,18 +189,21 @@ class OnboardingViewModel @AssistedInject constructor( } private fun continueToPageAfterSplash(onboardingFlow: OnboardingFlow) { - val nextOnboardingStep = when (onboardingFlow) { - OnboardingFlow.SignUp -> if (vectorFeatures.isOnboardingUseCaseEnabled()) { - OnboardingViewEvents.OpenUseCaseSelection - } else { - OnboardingViewEvents.OpenServerSelection + when (onboardingFlow) { + OnboardingFlow.SignUp -> { + _viewEvents.post( + if (vectorFeatures.isOnboardingUseCaseEnabled()) { + OnboardingViewEvents.OpenUseCaseSelection + } else { + OnboardingViewEvents.OpenServerSelection + } + ) } - OnboardingFlow.SignIn -> if (vectorFeatures.isOnboardingCombinedRegisterEnabled()) { - OnboardingViewEvents.OpenCombinedLogin - } else OnboardingViewEvents.OpenServerSelection - OnboardingFlow.SignInSignUp -> OnboardingViewEvents.OpenServerSelection + OnboardingFlow.SignIn -> if (vectorFeatures.isOnboardingCombinedLoginEnabled()) { + handle(OnboardingAction.HomeServerChange.SelectHomeServer(defaultHomeserverUrl)) + } else _viewEvents.post(OnboardingViewEvents.OpenServerSelection) + OnboardingFlow.SignInSignUp -> _viewEvents.post(OnboardingViewEvents.OpenServerSelection) } - _viewEvents.post(nextOnboardingStep) } private fun handleUserAcceptCertificate(action: OnboardingAction.UserAcceptCertificate) { @@ -487,7 +491,7 @@ class OnboardingViewModel @AssistedInject constructor( private fun handleLoginOrRegister(action: OnboardingAction.LoginOrRegister) = withState { state -> when (state.signMode) { SignMode.Unknown -> error("Developer error, invalid sign mode") - SignMode.SignIn -> handleLogin(action) + SignMode.SignIn -> handleLogin(OnboardingAction.Login(action.username, action.password, action.initialDeviceName)) SignMode.SignUp -> handleRegisterWith(OnboardingAction.Register(action.username, action.password, action.initialDeviceName)) SignMode.SignInWithMatrixId -> handleDirectLogin(action, null) } @@ -506,7 +510,7 @@ class OnboardingViewModel @AssistedInject constructor( } } - private fun handleLogin(action: OnboardingAction.LoginOrRegister) { + private fun handleLogin(action: OnboardingAction.Login) { val safeLoginWizard = loginWizard if (safeLoginWizard == null) { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt new file mode 100644 index 0000000000..66c7199acb --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt @@ -0,0 +1,198 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Build +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import androidx.autofill.HintConstants +import androidx.core.text.isDigitsOnly +import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.withState +import im.vector.app.R +import im.vector.app.core.extensions.content +import im.vector.app.core.extensions.editText +import im.vector.app.core.extensions.hasContentFlow +import im.vector.app.core.extensions.hasSurroundingSpaces +import im.vector.app.core.extensions.hideKeyboard +import im.vector.app.core.extensions.hidePassword +import im.vector.app.core.extensions.realignPercentagesToParent +import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.databinding.FragmentFtueCombinedLoginBinding +import im.vector.app.features.login.LoginMode +import im.vector.app.features.login.SSORedirectRouterActivity +import im.vector.app.features.login.SocialLoginButtonsView +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewEvents +import im.vector.app.features.onboarding.OnboardingViewState +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider +import org.matrix.android.sdk.api.failure.isInvalidPassword +import org.matrix.android.sdk.api.failure.isInvalidUsername +import org.matrix.android.sdk.api.failure.isLoginEmailUnknown +import javax.inject.Inject + +class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueCombinedLoginBinding { + return FragmentFtueCombinedLoginBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupSubmitButton() + views.createAccountRoot.realignPercentagesToParent() + views.editServerButton.debouncedClicks { + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) + } + + views.createAccountPasswordInput.editText().setOnEditorActionListener { _, actionId, _ -> + if (actionId == EditorInfo.IME_ACTION_DONE) { + submit() + return@setOnEditorActionListener true + } + return@setOnEditorActionListener false + } + } + + private fun setupSubmitButton() { + views.createAccountSubmit.setOnClickListener { submit() } + observeInputFields() + .onEach { + views.createAccountPasswordInput.error = null + views.createAccountInput.error = null + views.createAccountSubmit.isEnabled = it + } + .launchIn(viewLifecycleOwner.lifecycleScope) + } + + private fun observeInputFields() = combine( + views.createAccountInput.hasContentFlow { it.trim() }, + views.createAccountPasswordInput.hasContentFlow(), + transform = { isLoginNotEmpty, isPasswordNotEmpty -> isLoginNotEmpty && isPasswordNotEmpty } + ) + + private fun submit() { + withState(viewModel) { state -> + cleanupUi() + + val login = views.createAccountInput.content() + val password = views.createAccountPasswordInput.content() + + // This can be called by the IME action, so deal with empty cases + var error = 0 + if (login.isEmpty()) { + views.createAccountInput.error = getString(R.string.error_empty_field_choose_user_name) + error++ + } + if (state.isNumericOnlyUserIdForbidden() && login.isDigitsOnly()) { + views.createAccountInput.error = getString(R.string.error_forbidden_digits_only_username) + error++ + } + if (password.isEmpty()) { + views.createAccountPasswordInput.error = getString(R.string.error_empty_field_choose_password) + error++ + } + + if (error == 0) { + viewModel.handle(OnboardingAction.Login(login, password, getString(R.string.login_default_session_public_name))) + } + } + } + + private fun cleanupUi() { + views.createAccountSubmit.hideKeyboard() + views.createAccountInput.error = null + views.createAccountPasswordInput.error = null + } + + override fun resetViewModel() { + viewModel.handle(OnboardingAction.ResetAuthenticationAttempt) + } + + override fun onError(throwable: Throwable) { + // Trick to display the error without text. + views.createAccountInput.error = " " + when { + throwable.isInvalidUsername() -> { + views.createAccountInput.error = errorFormatter.toHumanReadable(throwable) + } + throwable.isLoginEmailUnknown() -> { + views.createAccountInput.error = getString(R.string.login_login_with_email_error) + } + throwable.isInvalidPassword() && views.createAccountPasswordInput.hasSurroundingSpaces() -> { + views.createAccountPasswordInput.error = getString(R.string.auth_invalid_login_param_space_in_password) + } + else -> { + super.onError(throwable) + } + } + } + + override fun updateWithState(state: OnboardingViewState) { + setupUi(state) + setupAutoFill() + + views.selectedServerName.text = state.selectedHomeserver.userFacingUrl.toReducedUrl() + views.selectedServerDescription.text = state.selectedHomeserver.description + + if (state.isLoading) { + // Ensure password is hidden + views.createAccountPasswordInput.editText().hidePassword() + } + } + + private fun setupUi(state: OnboardingViewState) { + when (state.selectedHomeserver.preferredLoginMode) { + is LoginMode.SsoAndPassword -> renderSsoProviders(state.deviceId, state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders) + else -> hideSsoProviders() + } + } + + private fun renderSsoProviders(deviceId: String?, ssoProviders: List?) { + views.ssoGroup.isVisible = ssoProviders?.isNotEmpty() == true + views.ssoButtons.mode = SocialLoginButtonsView.Mode.MODE_CONTINUE + views.ssoButtons.ssoIdentityProviders = ssoProviders?.sorted() + views.ssoButtons.listener = SocialLoginButtonsView.InteractionListener { id -> + viewModel.getSsoUrl( + redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, + deviceId = deviceId, + providerId = id + )?.let { openInCustomTab(it) } + } + } + + private fun hideSsoProviders() { + views.ssoGroup.isVisible = false + views.ssoButtons.ssoIdentityProviders = null + } + + private fun setupAutoFill() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + views.createAccountInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME) + views.createAccountPasswordInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD) + } + } + + private fun OnboardingViewState.isNumericOnlyUserIdForbidden() = selectedHomeserver.userFacingUrl == getString(R.string.matrix_org_server_url) +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index d7b8171225..5ad6b7e78d 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -233,7 +233,7 @@ class FtueAuthVariant( } private fun onStartCombinedLogin() { - addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java) + addRegistrationStageFragmentToBackstack(FtueAuthCombinedLoginFragment::class.java) } private fun onRegistrationFlow(viewEvents: OnboardingViewEvents.RegistrationFlowResult) { diff --git a/vector/src/main/res/layout/fragment_ftue_combined_login.xml b/vector/src/main/res/layout/fragment_ftue_combined_login.xml new file mode 100644 index 0000000000..684d6cf671 --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_combined_login.xml @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + +