diff --git a/.editorconfig b/.editorconfig index 0a49eadc0b..1966f91763 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,25 +9,6 @@ insert_final_newline=true # it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide) max_line_length=off -# Comma-separated list of rules to disable (Since 0.34.0) -# Note that rules in any ruleset other than the standard ruleset will need to be prefixed -# by the ruleset identifier. -disabled_rules=no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation - -# The following (so far identified) rules are kept: -# no-blank-line-before-rbrace -# final-newline -# no-consecutive-blank-lines -# comment-spacing -# filename -# comma-spacing -# paren-spacing -# op-spacing -# string-template -# no-unused-imports -# curly-spacing -# no-semi -# no-empty-class-body -# experimental:multiline-if-else -# experimental:no-empty-first-line-in-method-block -# no-wildcard-imports +# From https://github.com/pinterest/ktlint#custom-ktlint-specific-editorconfig-properties +# default IntelliJ IDEA style, same as alphabetical, but with "java", "javax", "kotlin" and alias imports in the end of the imports list +ij_kotlin_imports_layout=*,java.**,javax.**,kotlin.**,^ diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index dcb9f0a766..38885e9cc7 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -23,12 +23,12 @@ body: - type: textarea id: result attributes: - label: What happened? + label: Intended result and actual result placeholder: Tell us what went wrong value: | - ### What did you expect? + #### What did you expect? - ### What happened? + #### What happened instead? validations: required: true - type: input diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml index 4fecde2e90..903c05c5d3 100644 --- a/.github/ISSUE_TEMPLATE/release.yml +++ b/.github/ISSUE_TEMPLATE/release.yml @@ -1,7 +1,7 @@ name: Release checklist description: Checklist for each release. This template is only for the core team. title: "[Release] Element Android v" -labels: [\U0001F680 Release] +labels: [🚀 Release] assignees: - bmarty diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 0f11915258..5ccd00a02b 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -14,15 +14,19 @@ jobs: - name: Run code quality check suite run: ./tools/check/check_code_quality.sh - klint: + ktlint: name: Kotlin Linter runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Run klint + - name: Run ktlint run: | - curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.36.0/ktlint && chmod a+x ktlint - ./ktlint --android --experimental -v + ./gradlew ktlintCheck --continue + - name: Upload reports + uses: actions/upload-artifact@v2 + with: + name: ktlinting-report + path: vector/build/reports/ktlint/*.* # Lint for main module and all the other modules android-lint: diff --git a/.gitignore b/.gitignore index 935a3fc329..ff086d7723 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,4 @@ /fastlane/private /fastlane/report.xml -ktlint +/library/build diff --git a/CHANGES.md b/CHANGES.md index 8d4899e6fb..4b76ccce84 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,49 @@ +Changes in Element v1.3.2 (2021-10-08) +====================================== + +Features ✨ +---------- + - Android Auto notification support ([#240](https://github.com/vector-im/element-android/issues/240)) + - Add a fallback for user displayName when this one is null or empty ([#3732](https://github.com/vector-im/element-android/issues/3732)) + - Add client base url config to customize permalinks ([#4027](https://github.com/vector-im/element-android/issues/4027)) + - Check if DM exists before creating a new one ([#4157](https://github.com/vector-im/element-android/issues/4157)) + - Handle 8 new slash commands: `/ignore`, `/unignore`, `/roomname`, `/myroomnick`, `/roomavatar`, `/myroomavatar`, `/lenny`, `/whois`. ([#4158](https://github.com/vector-im/element-android/issues/4158)) + - Display identity server policies in the Discovery screen ([#4184](https://github.com/vector-im/element-android/issues/4184)) + +Bugfixes 🐛 +---------- + - Ensure initial sync progress dialog is hidden when the initial sync is over ([#983](https://github.com/vector-im/element-android/issues/983)) + - Avoid resending notifications that are already shown ([#1673](https://github.com/vector-im/element-android/issues/1673)) + - Room filter no results bad CTA in space mode when a space selected ([#3048](https://github.com/vector-im/element-android/issues/3048)) + - Fixes notifications not dismissing when reading messages on other devices ([#3347](https://github.com/vector-im/element-android/issues/3347)) + - Fixes the passphrase screen being incorrectly shown when pressing back on the key verification screen. + When the user doesn't have a passphrase set we don't show the passphrase screen. ([#3898](https://github.com/vector-im/element-android/issues/3898)) + - App doesn't take you to a Space after choosing to Join it ([#3933](https://github.com/vector-im/element-android/issues/3933)) + - Validate public space addresses and room aliases length ([#3934](https://github.com/vector-im/element-android/issues/3934)) + - Save button for adding rooms to a space is hidden when scrolling through list of rooms ([#3935](https://github.com/vector-im/element-android/issues/3935)) + - Align new room encryption default to Web ([#4045](https://github.com/vector-im/element-android/issues/4045)) + - Fix Reply/Edit mode animation is broken when sending ([#4077](https://github.com/vector-im/element-android/issues/4077)) + - Added changes that will make SearchView in search bar focused by default on opening reaction picker. + + When tapping close icon of SearchView, the SearchView did not collapse therefore added the on close listener + which will collapse the SearchView on close. ([#4092](https://github.com/vector-im/element-android/issues/4092)) + - Troubleshoot notification: Fix button not clickable ([#4109](https://github.com/vector-im/element-android/issues/4109)) + - Harmonize wording in the message bottom sheet and move up the View Reactions item ([#4155](https://github.com/vector-im/element-android/issues/4155)) + - Remove unused SendRelationWorker and related API call (3588) ([#4156](https://github.com/vector-im/element-android/issues/4156)) + - SIP user to native user mapping is wrong ([#4176](https://github.com/vector-im/element-android/issues/4176)) + +SDK API changes ⚠️ +------------------ + - Create extension `String.isMxcUrl()` ([#4158](https://github.com/vector-im/element-android/issues/4158)) + +Other changes +------------- + - Use ktlint plugin. See [the documentation](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#ktlint) for more detail. ([#3957](https://github.com/vector-im/element-android/issues/3957)) + - Minimize the use of exported="true" in android Manifest (link: https://github.com/matrix-org/matrix-dinsic/issues/618) ([#4018](https://github.com/vector-im/element-android/issues/4018)) + - Fix redundancy in heading in the bug report issue form ([#4076](https://github.com/vector-im/element-android/issues/4076)) + - Fix release label in the release issue template ([#4113](https://github.com/vector-im/element-android/issues/4113)) + + Changes in Element v1.3.1 (2021-09-29) ====================================== diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1d213e6b7..dbc0ce9b72 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ Android support can be found in this [![Element Android Matrix room #element-and ## Android Studio settings Please set the "hard wrap" setting of Android Studio to 160 chars, this is the setting we use internally to format the source code (Menu `Settings/Editor/Code Style` then `Hard wrap at`). -Please ensure that your using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them. +Please ensure that you're using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them. ### Template @@ -80,14 +80,13 @@ Make sure the following commands execute without any error: #### ktlint
-curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint
-./ktlint --android --experimental -v
+./gradlew ktlintCheck --continue
 
Note that you can run
-./ktlint --android --experimental -v -F
+./gradlew ktlintFormat
 
For ktlint to fix some detected errors for you (you still have to check and commit the fix of course) diff --git a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt index f909418d6f..4ca6ced8fe 100644 --- a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt +++ b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt @@ -39,7 +39,6 @@ import androidx.core.view.updatePadding import androidx.transition.TransitionManager import androidx.viewpager2.widget.ViewPager2 import im.vector.lib.attachmentviewer.databinding.ActivityAttachmentViewerBinding - import java.lang.ref.WeakReference import kotlin.math.abs @@ -291,8 +290,8 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private fun calculateTranslationAlpha(translationY: Float, translationLimit: Int): Float = 1.0f - 1.0f / translationLimit.toFloat() / 4f * abs(translationY) - private fun createSwipeToDismissHandler() - : SwipeToDismissHandler = SwipeToDismissHandler( + private fun createSwipeToDismissHandler(): SwipeToDismissHandler = + SwipeToDismissHandler( swipeView = views.dismissContainer, shouldAnimateDismiss = { shouldAnimateDismiss() }, onDismiss = { animateClose() }, diff --git a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/ImageLoaderTarget.kt b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/ImageLoaderTarget.kt index 531e8171e1..99686eaabb 100644 --- a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/ImageLoaderTarget.kt +++ b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/ImageLoaderTarget.kt @@ -36,8 +36,8 @@ interface ImageLoaderTarget { fun onResourceReady(uid: String, resource: Drawable) } -internal class DefaultImageLoaderTarget(val holder: AnimatedImageViewHolder, private val contextView: ImageView) - : ImageLoaderTarget { +internal class DefaultImageLoaderTarget(val holder: AnimatedImageViewHolder, private val contextView: ImageView) : + ImageLoaderTarget { override fun contextView(): ImageView { return contextView } diff --git a/build.gradle b/build.gradle index 49c3e07ece..93f3e17f34 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,14 @@ buildscript { } } +// ktlint Plugin +plugins { + id "org.jlleitschuh.gradle.ktlint" version "10.2.0" +} + allprojects { + apply plugin: "org.jlleitschuh.gradle.ktlint" + repositories { // For olm library. This has to be declared first, to ensure that Olm library is not downloaded from another repo maven { @@ -75,6 +82,26 @@ allprojects { // You can override by passing `-PallWarningsAsErrors=false` in the command line kotlinOptions.allWarningsAsErrors = project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean() } + + // Fix "Java heap space" issue + tasks.withType(org.jlleitschuh.gradle.ktlint.tasks.BaseKtLintCheckTask).configureEach { + it.workerMaxHeapSize.set("2G") + } + + // See https://github.com/JLLeitschuh/ktlint-gradle#configuration + ktlint { + android = true + ignoreFailures = false + enableExperimentalRules = true + // display the corresponding rule + verbose = true + disabledRules = [ + "spacing-between-declarations-with-comments", + "no-multi-spaces", + "experimental:spacing-between-declarations-with-annotations", + "experimental:annotation" + ] + } } task clean(type: Delete) { diff --git a/dependencies.gradle b/dependencies.gradle index f19c1d3539..92358952db 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -9,9 +9,9 @@ ext.versions = [ def gradle = "7.0.2" // Ref: https://kotlinlang.org/releases.html -def kotlin = "1.5.30" -def kotlinCoroutines = "1.5.1" -def dagger = "2.38.1" +def kotlin = "1.5.31" +def kotlinCoroutines = "1.5.2" +def dagger = "2.39.1" def retrofit = "2.9.0" def arrow = "0.8.2" def markwon = "4.6.2" @@ -49,7 +49,7 @@ ext.libs = [ 'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3", 'fragmentKtx' : "androidx.fragment:fragment-ktx:1.3.6", 'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.1", - 'work' : "androidx.work:work-runtime-ktx:2.5.0", + 'work' : "androidx.work:work-runtime-ktx:2.6.0", 'autoFill' : "androidx.autofill:autofill:1.1.0", 'preferenceKtx' : "androidx.preference:preference-ktx:1.1.1", 'junit' : "androidx.test.ext:junit:1.1.3", diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40103000.txt b/fastlane/metadata/android/cs-CZ/changelogs/40103000.txt new file mode 100644 index 0000000000..f97ff3ef3a --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Uspořádejte si místnosti pomocí Prostorů! +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/en-US/changelogs/40103020.txt b/fastlane/metadata/android/en-US/changelogs/40103020.txt new file mode 100644 index 0000000000..7ac48f4890 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40103020.txt @@ -0,0 +1,2 @@ +Main changes in this version: Add support for Android Auto. Lot of bug fixes! +Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.3.2 \ No newline at end of file diff --git a/fastlane/metadata/android/et/changelogs/40103000.txt b/fastlane/metadata/android/et/changelogs/40103000.txt new file mode 100644 index 0000000000..643ae1ce0e --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: halda oma jututubasid koondades neid uut tüüpi kogukondadesse! +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/fa/changelogs/40103000.txt b/fastlane/metadata/android/fa/changelogs/40103000.txt new file mode 100644 index 0000000000..ba43459c0a --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40103000.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: سازمان‌دهی اتاق‌هایتان با استفاده از فضاها +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40102000.txt b/fastlane/metadata/android/fr-FR/changelogs/40102000.txt index 504c3e24be..0bcf3551f6 100644 --- a/fastlane/metadata/android/fr-FR/changelogs/40102000.txt +++ b/fastlane/metadata/android/fr-FR/changelogs/40102000.txt @@ -1,2 +1,2 @@ -Principaux changements pour cette version : messages vocaux activés par défault. -Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.16 +Principaux changements pour cette version : messages vocaux activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.2.0 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40102010.txt b/fastlane/metadata/android/fr-FR/changelogs/40102010.txt new file mode 100644 index 0000000000..910d4bd9c0 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40102010.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Beaucoup d’améliorations sur la VoIP et les Espaces (toujours en bêta). +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.2.1 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40103000.txt b/fastlane/metadata/android/fr-FR/changelogs/40103000.txt new file mode 100644 index 0000000000..66c2c3db86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Organisez vous salons à l’aide des Espaces ! +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/hu-HU/changelogs/40103000.txt b/fastlane/metadata/android/hu-HU/changelogs/40103000.txt new file mode 100644 index 0000000000..40673b30b1 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Szobák terekbe szervezése +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/id/changelogs/40102000.txt b/fastlane/metadata/android/id/changelogs/40102000.txt index 2258b114e8..f7d93e2e4f 100644 --- a/fastlane/metadata/android/id/changelogs/40102000.txt +++ b/fastlane/metadata/android/id/changelogs/40102000.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Pesan Suara diaktifkan secara default -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.16 +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.0 diff --git a/fastlane/metadata/android/id/changelogs/40102010.txt b/fastlane/metadata/android/id/changelogs/40102010.txt new file mode 100644 index 0000000000..e77f0327b0 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40102010.txt @@ -0,0 +1,2 @@ +Perubahan utama di versi ini: Banyak perbaikan di VoIP dan Space (masih beta). +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.1 diff --git a/fastlane/metadata/android/id/changelogs/40103000.txt b/fastlane/metadata/android/id/changelogs/40103000.txt new file mode 100644 index 0000000000..bf7b5d8d5d --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Perubahan utama di versi ini: Organisir ruangan Anda menggunakan sebuah Space! +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt index 75249c6a20..bd357bb161 100644 --- a/fastlane/metadata/android/id/full_description.txt +++ b/fastlane/metadata/android/id/full_description.txt @@ -11,7 +11,7 @@ Element adalah perpesanan yang aman dan aplikasi kolaborasi tim produktivitas ya Element benar-benar berbeda dari aplikasi perpesanan dan kolaborasi lainnya. Element beroperasi pada Matrix, jaringan terbuka untuk pengiriman pesan yang aman dan komunikasi terdesentralisasi. Matrix memungkinkan hosting sendiri untuk memberi pengguna kepemilikan maksimum dan kontrol data dan pesan mereka. Pesan privasi dan terenkripsi -Element melindungi Anda dari iklan yang tidak diinginkan, data penambangan dan taman berdinding. Element juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu melalui enkripsi ujung-ke-ujung dan verifikasi perangkat yang ditanda tangani silang. +Element melindungi Anda dari iklan yang tidak diinginkan, penambangan data dan taman berdinding. Element juga mengamankan semua data Anda, komunikasi video dan suara satu-ke-satu melalui enkripsi ujung-ke-ujung dan verifikasi perangkat yang ditandatangani secara silang. Element memberi Anda kendali atas privasi Anda sambil memungkinkan Anda untuk berkomunikasi dengan aman dengan siapa pun di jaringan Matrix, atau alat kolaborasi bisnis lainnya dengan mengintegrasikan dengan aplikasi seperti Slack. diff --git a/fastlane/metadata/android/it-IT/changelogs/40103000.txt b/fastlane/metadata/android/it-IT/changelogs/40103000.txt new file mode 100644 index 0000000000..6ad9001bfd --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: organizza le tue stanze usando gli Spazi! +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/pt-BR/changelogs/40103000.txt b/fastlane/metadata/android/pt-BR/changelogs/40103000.txt new file mode 100644 index 0000000000..c046c1cbc9 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Organize suas salas usando Espaços! +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/sq/changelogs/40103000.txt b/fastlane/metadata/android/sq/changelogs/40103000.txt new file mode 100644 index 0000000000..ecd5568c02 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Ndryshime kryesore në këtë version: Sistemoni dhomat tuaja duke përdorur Hapësira! +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/sv-SE/changelogs/40102010.txt b/fastlane/metadata/android/sv-SE/changelogs/40102010.txt new file mode 100644 index 0000000000..f29b95de79 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40102010.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Många förbättringar för VoIP och utrymmen (fortfarande i beta). +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.2.1 diff --git a/fastlane/metadata/android/sv-SE/changelogs/40103000.txt b/fastlane/metadata/android/sv-SE/changelogs/40103000.txt new file mode 100644 index 0000000000..d9a2c34f1d --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Organisera dina rum med utrymmen! +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/uk/changelogs/40103000.txt b/fastlane/metadata/android/uk/changelogs/40103000.txt new file mode 100644 index 0000000000..64a168cbe9 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Упорядковуйте свої кімнати за допомогою Просторів! +Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/zh-CN/changelogs/40103000.txt b/fastlane/metadata/android/zh-CN/changelogs/40103000.txt new file mode 100644 index 0000000000..96ec8b3322 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/40103000.txt @@ -0,0 +1,2 @@ +此版本主要更改:使用空间组织你的聊天室! +完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/zh-TW/changelogs/40103000.txt b/fastlane/metadata/android/zh-TW/changelogs/40103000.txt new file mode 100644 index 0000000000..fbae69cd21 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40103000.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:使用空間來整理您的聊天室! +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/LiveDataObservable.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/LiveDataObservable.kt index 2174c6f118..56b52facf9 100644 --- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/LiveDataObservable.kt +++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/LiveDataObservable.kt @@ -34,8 +34,8 @@ private class LiveDataObservable( liveData.observeForever(relay) } - private inner class RemoveObserverInMainThread(private val observer: io.reactivex.Observer) - : MainThreadDisposable(), Observer { + private inner class RemoveObserverInMainThread(private val observer: io.reactivex.Observer) : + MainThreadDisposable(), Observer { override fun onChanged(t: T?) { if (!isDisposed) { diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/OptionalRx.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/OptionalRx.kt index ff4b0d755c..936bd824e7 100644 --- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/OptionalRx.kt +++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/OptionalRx.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.rx -import org.matrix.android.sdk.api.util.Optional import io.reactivex.Observable +import org.matrix.android.sdk.api.util.Optional fun Observable>.unwrap(): Observable { return filter { it.hasValue() }.map { it.get() } diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 2be6106d41..e3c8d7c4f1 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -31,7 +31,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.3.1\"" + buildConfigField "String", "SDK_VERSION", "\"1.3.2\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" resValue "string", "git_sdk_revision", "\"${gitRevision()}\"" @@ -115,7 +115,7 @@ dependencies { implementation libs.squareup.retrofit implementation libs.squareup.retrofitMoshi - implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.1")) + implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.2")) implementation 'com.squareup.okhttp3:okhttp' implementation 'com.squareup.okhttp3:logging-interceptor' implementation 'com.squareup.okhttp3:okhttp-urlconnection' @@ -154,7 +154,7 @@ dependencies { implementation 'com.otaliastudios:transcoder:0.10.4' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.33' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.34' testImplementation libs.tests.junit testImplementation 'org.robolectric:robolectric:4.6.1' diff --git a/matrix-sdk-android/src/androidTest/AndroidManifest.xml b/matrix-sdk-android/src/androidTest/AndroidManifest.xml index 274bd8c87b..40360fcd19 100644 --- a/matrix-sdk-android/src/androidTest/AndroidManifest.xml +++ b/matrix-sdk-android/src/androidTest/AndroidManifest.xml @@ -8,10 +8,15 @@ This is mandatory to run integration tests --> + tools:node="merge"> + + diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/InstrumentedTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/InstrumentedTest.kt index 583406346e..a763766821 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/InstrumentedTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/InstrumentedTest.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk import android.content.Context import androidx.test.core.app.ApplicationProvider -import org.matrix.android.sdk.test.shared.createTimberTestRule import org.junit.Rule +import org.matrix.android.sdk.test.shared.createTimberTestRule interface InstrumentedTest { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SingleThreadCoroutineDispatcher.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SingleThreadCoroutineDispatcher.kt index 9942ea9db3..192f6442b2 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SingleThreadCoroutineDispatcher.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/SingleThreadCoroutineDispatcher.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.asCoroutineDispatcher +import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import java.util.concurrent.Executors internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main, diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/AccountCreationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/AccountCreationTest.kt index 5dede9dcfd..e0451bea38 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/AccountCreationTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/AccountCreationTest.kt @@ -16,16 +16,16 @@ package org.matrix.android.sdk.account -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.common.CommonTestHelper -import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.common.SessionTestParams -import org.matrix.android.sdk.common.TestConstants 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.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.SessionTestParams +import org.matrix.android.sdk.common.TestConstants @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt index 103b638c39..d32bcb3fe5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt @@ -16,17 +16,17 @@ package org.matrix.android.sdk.account -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.failure.isInvalidPassword -import org.matrix.android.sdk.common.CommonTestHelper -import org.matrix.android.sdk.common.SessionTestParams -import org.matrix.android.sdk.common.TestConstants import org.amshove.kluent.shouldBeTrue 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.failure.isInvalidPassword +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.SessionTestParams +import org.matrix.android.sdk.common.TestConstants @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt index 01c4f8ccb3..f8d108fb73 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt @@ -67,9 +67,9 @@ class DeactivateAccountTest : InstrumentedTest { val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD) // Test the error - assertTrue(throwable is Failure.ServerError - && throwable.error.code == MatrixError.M_USER_DEACTIVATED - && throwable.error.message == "This account has been deactivated") + assertTrue(throwable is Failure.ServerError && + throwable.error.code == MatrixError.M_USER_DEACTIVATED && + throwable.error.message == "This account has been deactivated") // Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE) val hs = commonTestHelper.createHomeServerConfig() @@ -95,8 +95,8 @@ class DeactivateAccountTest : InstrumentedTest { // Test the error accountCreationError.let { - assertTrue(it is Failure.ServerError - && it.error.code == MatrixError.M_USER_IN_USE) + assertTrue(it is Failure.ServerError && + it.error.code == MatrixError.M_USER_IN_USE) } // No need to close the session, it has been deactivated diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/MockOkHttpInterceptor.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/MockOkHttpInterceptor.kt index e7978a9cb2..b6d833a77c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/MockOkHttpInterceptor.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/MockOkHttpInterceptor.kt @@ -15,12 +15,12 @@ */ package org.matrix.android.sdk.common -import org.matrix.android.sdk.internal.session.TestInterceptor import okhttp3.Interceptor import okhttp3.Protocol import okhttp3.Request import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody +import org.matrix.android.sdk.internal.session.TestInterceptor import javax.net.ssl.HttpsURLConnection /** diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixCallback.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixCallback.kt index c2e1ec0f92..9f6d6eb136 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixCallback.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixCallback.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.common import androidx.annotation.CallSuper -import org.matrix.android.sdk.api.MatrixCallback import org.junit.Assert.fail +import org.matrix.android.sdk.api.MatrixCallback import timber.log.Timber import java.util.concurrent.CountDownLatch diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt index b6cb7f9e79..aaf779212b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt @@ -26,9 +26,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments +import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import java.io.ByteArrayOutputStream import java.io.InputStream diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt index 75ccce0db9..c717c8e33f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreHelper.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto +import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper import org.matrix.android.sdk.internal.di.MoshiProvider -import io.realm.RealmConfiguration import kotlin.random.Random internal class CryptoStoreHelper { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt index 1d838b5c84..f43c425cc9 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/CryptoStoreTest.kt @@ -17,9 +17,6 @@ package org.matrix.android.sdk.internal.crypto import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import io.realm.Realm import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals @@ -27,6 +24,9 @@ import org.junit.Assert.assertNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper +import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.olm.OlmAccount import org.matrix.olm.OlmManager import org.matrix.olm.OlmSession diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt index a2566c1414..825fba570a 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt @@ -50,8 +50,8 @@ class PreShareKeysTest : InstrumentedTest { aliceSession.cryptoService().discardOutboundSession(e2eRoomID) val preShareCount = bobSession.cryptoService().getGossipingEvents().count { - it.senderId == aliceSession.myUserId - && it.getClearType() == EventType.ROOM_KEY + it.senderId == aliceSession.myUserId && + it.getClearType() == EventType.ROOM_KEY } assertEquals("Bob should not have receive any key from alice at this point", 0, preShareCount) @@ -65,16 +65,16 @@ class PreShareKeysTest : InstrumentedTest { mTestHelper.waitWithLatch { latch -> mTestHelper.retryPeriodicallyWithLatch(latch) { val newGossipCount = bobSession.cryptoService().getGossipingEvents().count { - it.senderId == aliceSession.myUserId - && it.getClearType() == EventType.ROOM_KEY + it.senderId == aliceSession.myUserId && + it.getClearType() == EventType.ROOM_KEY } newGossipCount > preShareCount } } val latest = bobSession.cryptoService().getGossipingEvents().lastOrNull { - it.senderId == aliceSession.myUserId - && it.getClearType() == EventType.ROOM_KEY + it.senderId == aliceSession.myUserId && + it.getClearType() == EventType.ROOM_KEY } val content = latest?.getClearContent().toModel() diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index b2516ea2be..c939952dc9 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -18,6 +18,11 @@ package org.matrix.android.sdk.internal.crypto.gossiping import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.tryOrNull @@ -31,11 +36,6 @@ import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode -import org.junit.Assert -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt index cc71f88fc0..63e74603d0 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPasswordTest.kt @@ -17,9 +17,6 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.listeners.ProgressListener -import org.matrix.android.sdk.common.assertByteArrayNotEqual import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -28,6 +25,9 @@ import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.listeners.ProgressListener +import org.matrix.android.sdk.common.assertByteArrayNotEqual import org.matrix.olm.OlmManager import org.matrix.olm.OlmPkDecryption 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 89d297c592..0785dba8b9 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 @@ -17,6 +17,16 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener @@ -33,16 +43,6 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreat import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull -import org.junit.Assert.assertTrue -import org.junit.Assert.fail -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters import java.util.ArrayList import java.util.Collections import java.util.concurrent.CountDownLatch 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 b6e5ae7364..a625ffc0e9 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 @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup +import org.junit.Assert import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService @@ -28,7 +29,6 @@ import org.matrix.android.sdk.common.assertListEquals import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.junit.Assert import java.util.concurrent.CountDownLatch class KeysBackupTestHelper( diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/StateObserver.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/StateObserver.kt index ff8ce43b55..80e54d82ec 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/StateObserver.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/StateObserver.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.keysbackup +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNull import java.util.concurrent.CountDownLatch /** @@ -91,8 +91,8 @@ internal class StateObserver(private val keysBackup: KeysBackupService, stateList.add(newState) // Check that state transition is valid - if (stateList.size >= 2 - && !allowedStateTransitions.contains(stateList[stateList.size - 2] to newState)) { + if (stateList.size >= 2 && + !allowedStateTransitions.contains(stateList[stateList.size - 2] to newState)) { // Forbidden transition detected lastTransitionError = "Forbidden transition detected from " + stateList[stateList.size - 2] + " to " + newState } 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 74855b8630..b343d7334a 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 @@ -18,8 +18,20 @@ package org.matrix.android.sdk.internal.crypto.ssss import androidx.lifecycle.Observer import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest 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.KeySigner import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec @@ -33,18 +45,6 @@ import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorageService -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt index 4ea8cdc074..e0d49b3f5e 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt @@ -18,6 +18,16 @@ package org.matrix.android.sdk.internal.crypto.verification import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.CancelCode @@ -38,16 +48,6 @@ import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.crypto.model.rest.toValue -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull -import org.junit.Assert.assertTrue -import org.junit.Assert.fail -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) @@ -551,7 +551,7 @@ class SASTest : InstrumentedTest { cryptoTestData.roomId ) - var requestID : String? = null + var requestID: String? = null mTestHelper.waitWithLatch { mTestHelper.retryPeriodicallyWithLatch(it) { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt index 97b93dcf5a..9b10f9e9af 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt @@ -17,13 +17,13 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.InstrumentedTest import org.amshove.kluent.shouldBe import org.amshove.kluent.shouldNotBeEqualTo import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt index 94303dda08..1ed2f89977 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt @@ -25,6 +25,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.common.TestRoomDisplayNameFallbackProvider +import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import org.matrix.android.sdk.internal.session.room.send.pills.MentionLinkSpecComparator import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils @@ -48,7 +51,14 @@ class MarkdownParserTest : InstrumentedTest { private val markdownParser = MarkdownParser( Parser.builder().build(), HtmlRenderer.builder().softbreak("
").build(), - TextPillsUtils(MentionLinkSpecComparator()) + TextPillsUtils( + MentionLinkSpecComparator(), + DisplayNameResolver( + MatrixConfiguration( + applicationFlavor = "TestFlavor", + roomDisplayNameFallbackProvider = TestRoomDisplayNameFallbackProvider() + ) + )) ) @Test diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/util/JsonCanonicalizerTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/util/JsonCanonicalizerTest.kt index b5ab6589ff..d38afc6b62 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/util/JsonCanonicalizerTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/util/JsonCanonicalizerTest.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.util import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.InstrumentedTest import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith +import org.matrix.android.sdk.InstrumentedTest @RunWith(AndroidJUnit4::class) internal class JsonCanonicalizerTest : InstrumentedTest { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineBackToPreviousLastForwardTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineBackToPreviousLastForwardTest.kt index 3774e6f513..7628f287c9 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineBackToPreviousLastForwardTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineBackToPreviousLastForwardTest.kt @@ -16,6 +16,14 @@ package org.matrix.android.sdk.session.room.timeline +import org.amshove.kluent.shouldBeFalse +import org.amshove.kluent.shouldBeTrue +import org.junit.Assert.assertTrue +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.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.EventType @@ -26,14 +34,6 @@ 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.checkSendOrder -import org.amshove.kluent.shouldBeFalse -import org.amshove.kluent.shouldBeTrue -import org.junit.Assert.assertTrue -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.runners.MethodSorters import timber.log.Timber import java.util.concurrent.CountDownLatch @@ -111,8 +111,8 @@ class TimelineBackToPreviousLastForwardTest : InstrumentedTest { } // Ok, we have the 10 last messages from Alice. - snapshot.size == 10 - && snapshot.all { it.root.content.toModel()?.body?.startsWith(messageRoot).orFalse() } + snapshot.size == 10 && + snapshot.all { it.root.content.toModel()?.body?.startsWith(messageRoot).orFalse() } } bobTimeline.addListener(eventsListener) @@ -160,10 +160,10 @@ class TimelineBackToPreviousLastForwardTest : InstrumentedTest { } // Bob can see the first event of the room (so Back pagination has worked) - snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE + snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE && // 8 for room creation item, and 30 for the forward pagination - && snapshot.size == 38 - && snapshot.checkSendOrder(messageRoot, 30, 0) + snapshot.size == 38 && + snapshot.checkSendOrder(messageRoot, 30, 0) } bobTimeline.addListener(eventsListener) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineForwardPaginationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineForwardPaginationTest.kt index 0fe341cad6..dfa6ec10ae 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineForwardPaginationTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelineForwardPaginationTest.kt @@ -16,6 +16,13 @@ package org.matrix.android.sdk.session.room.timeline +import org.amshove.kluent.shouldBeFalse +import org.amshove.kluent.shouldBeTrue +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.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.EventType @@ -26,13 +33,6 @@ 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.checkSendOrder -import org.amshove.kluent.shouldBeFalse -import org.amshove.kluent.shouldBeTrue -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.runners.MethodSorters import timber.log.Timber import java.util.concurrent.CountDownLatch @@ -86,8 +86,8 @@ class TimelineForwardPaginationTest : InstrumentedTest { } // Ok, we have the 10 last messages of the initial sync - snapshot.size == 10 - && snapshot.all { it.root.content.toModel()?.body?.startsWith(message).orFalse() } + snapshot.size == 10 && + snapshot.all { it.root.content.toModel()?.body?.startsWith(message).orFalse() } } // Open the timeline at last sent message @@ -110,8 +110,8 @@ class TimelineForwardPaginationTest : InstrumentedTest { } // The event is not in db, so it is fetch alone - snapshot.size == 1 - && snapshot.all { it.root.content.toModel()?.body?.startsWith("Message from Alice").orFalse() } + snapshot.size == 1 && + snapshot.all { it.root.content.toModel()?.body?.startsWith("Message from Alice").orFalse() } } aliceTimeline.addListener(aliceEventsListener) @@ -137,9 +137,9 @@ class TimelineForwardPaginationTest : InstrumentedTest { } // Alice can see the first event of the room (so Back pagination has worked) - snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE + snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE && // 6 for room creation item (backward pagination), 1 for the context, and 50 for the forward pagination - && snapshot.size == 57 // 6 + 1 + 50 + snapshot.size == 57 // 6 + 1 + 50 } aliceTimeline.addListener(aliceEventsListener) @@ -166,8 +166,8 @@ class TimelineForwardPaginationTest : InstrumentedTest { Timber.w(" event ${it.root.content}") } // 6 for room creation item (backward pagination),and numberOfMessagesToSend (all the message of the room) - snapshot.size == 6 + numberOfMessagesToSend - && snapshot.checkSendOrder(message, numberOfMessagesToSend, 0) + snapshot.size == 6 + numberOfMessagesToSend && + snapshot.checkSendOrder(message, numberOfMessagesToSend, 0) } aliceTimeline.addListener(aliceEventsListener) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt index 03a4d41988..e865fe17da 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/room/timeline/TimelinePreviousLastForwardTest.kt @@ -16,6 +16,13 @@ package org.matrix.android.sdk.session.room.timeline +import org.amshove.kluent.shouldBeFalse +import org.amshove.kluent.shouldBeTrue +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.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.EventType @@ -26,13 +33,6 @@ 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.checkSendOrder -import org.amshove.kluent.shouldBeFalse -import org.amshove.kluent.shouldBeTrue -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.runners.MethodSorters import timber.log.Timber import java.util.concurrent.CountDownLatch @@ -107,8 +107,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { } // Ok, we have the 10 last messages from Alice. This will be our future previous lastForward chunk - snapshot.size == 10 - && snapshot.all { it.root.content.toModel()?.body?.startsWith(firstMessage).orFalse() } + snapshot.size == 10 && + snapshot.all { it.root.content.toModel()?.body?.startsWith(firstMessage).orFalse() } } bobTimeline.addListener(eventsListener) @@ -141,8 +141,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { } // Ok, we have the 10 last messages from Alice. This will be our future previous lastForward chunk - snapshot.size == 10 - && snapshot.all { it.root.content.toModel()?.body?.startsWith(secondMessage).orFalse() } + snapshot.size == 10 && + snapshot.all { it.root.content.toModel()?.body?.startsWith(secondMessage).orFalse() } } bobTimeline.addListener(eventsListener) @@ -216,11 +216,11 @@ class TimelinePreviousLastForwardTest : InstrumentedTest { } // Bob can see the first event of the room (so Back pagination has worked) - snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE + snapshot.lastOrNull()?.root?.getClearType() == EventType.STATE_ROOM_CREATE && // 8 for room creation item 60 message from Alice - && snapshot.size == 68 // 8 + 60 - && snapshot.checkSendOrder(secondMessage, 30, 0) - && snapshot.checkSendOrder(firstMessage, 30, 30) + snapshot.size == 68 && // 8 + 60 + snapshot.checkSendOrder(secondMessage, 30, 0) && + snapshot.checkSendOrder(firstMessage, 30, 30) } bobTimeline.addListener(eventsListener) diff --git a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt index 2103dc954d..3add757efa 100644 --- a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt +++ b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.network.interceptors -import org.matrix.android.sdk.internal.di.MatrixScope import okhttp3.Interceptor import okhttp3.Response import okio.Buffer +import org.matrix.android.sdk.internal.di.MatrixScope import timber.log.Timber import java.io.IOException import java.nio.charset.Charset @@ -36,8 +36,8 @@ import javax.inject.Inject * non-production environment. */ @MatrixScope -internal class CurlLoggingInterceptor @Inject constructor() - : Interceptor { +internal class CurlLoggingInterceptor @Inject constructor() : + Interceptor { /** * Set any additional curl command options (see 'curl --help'). @@ -90,8 +90,8 @@ internal class CurlLoggingInterceptor @Inject constructor() curlCmd += ((if (compressed) " --compressed " else " ") + "'" + request.url.toString() // Replace localhost for emulator by localhost for shell - .replace("://10.0.2.2:8080/".toRegex(), "://127.0.0.1:8080/") - + "'") + .replace("://10.0.2.2:8080/".toRegex(), "://127.0.0.1:8080/") + + "'") // Add Json formatting curlCmd += " | python -m json.tool" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index ed809cdb04..3359e253f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -32,14 +32,26 @@ data class MatrixConfiguration( "https://scalar-staging.riot.im/scalar/api" ), /** - * Optional proxy to connect to the matrix servers - * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port) + * Optional base url to create client permalinks (eg. https://www.example.com/#/) instead of Matrix ones (matrix.to links). + * Do not forget to add the "#" which is required by the permalink parser. + * + * Note: this field is only used for permalinks creation, you will also have to edit the string-array `permalink_supported_hosts` in the config file + * and add it to your manifest to handle these links in the application. + */ + val clientPermalinkBaseUrl: String? = null, + /** + * Optional proxy to connect to the matrix servers. + * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port). */ val proxy: Proxy? = null, /** * True to advertise support for call transfers to other parties on Matrix calls. */ val supportsCallTransfer: Boolean = false, + /** + * MatrixItemDisplayNameFallbackProvider to provide default display name for MatrixItem. By default, the id will be used + */ + val matrixItemDisplayNameFallbackProvider: MatrixItemDisplayNameFallbackProvider? = null, /** * RoomDisplayNameFallbackProvider to provide default room display name. */ @@ -47,7 +59,7 @@ data class MatrixConfiguration( ) { /** - * Can be implemented by your Application class + * Can be implemented by your Application class. */ interface Provider { fun providesMatrixConfiguration(): MatrixConfiguration diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConstants.kt new file mode 100644 index 0000000000..49520f3678 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConstants.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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 + +/** + * This object define some global constants regarding the Matrix specification + */ +object MatrixConstants { + /** + * Max length for an alias. Room aliases MUST NOT exceed 255 bytes (including the # sigil and the domain). + * See [maxAliasLocalPartLength] + * Ref. https://matrix.org/docs/spec/appendices#room-aliases + */ + const val ALIAS_MAX_LENGTH = 255 + + fun maxAliasLocalPartLength(domain: String): Int { + return (ALIAS_MAX_LENGTH - 1 /* # sigil */ - 1 /* ':' */ - domain.length) + .coerceAtLeast(0) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixItemDisplayNameFallbackProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixItemDisplayNameFallbackProvider.kt new file mode 100644 index 0000000000..82008cda8c --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixItemDisplayNameFallbackProvider.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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 + +import org.matrix.android.sdk.api.util.MatrixItem + +interface MatrixItemDisplayNameFallbackProvider { + fun getDefaultName(matrixItem: MatrixItem): String +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt index 9a5e40ffeb..2a26b612fb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt @@ -17,6 +17,8 @@ package org.matrix.android.sdk.api import org.matrix.android.sdk.BuildConfig +import org.matrix.android.sdk.internal.util.removeInvalidRoomNameChars +import org.matrix.android.sdk.internal.util.replaceSpaceChars import timber.log.Timber /** @@ -128,10 +130,10 @@ object MatrixPatterns { * @return true if the string is a valid event id. */ fun isEventId(str: String?): Boolean { - return str != null - && (str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER - || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 - || str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V4) + return str != null && + (str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER || + str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V3 || + str matches PATTERN_CONTAIN_MATRIX_EVENT_IDENTIFIER_V4) } /** @@ -162,10 +164,11 @@ object MatrixPatterns { return order != null && order.length < 50 && order matches ORDER_STRING_REGEX } - fun candidateAliasFromRoomName(name: String): String { - return Regex("\\s").replace(name.lowercase(), "_").let { - "[^a-z0-9._%#@=+-]".toRegex().replace(it, "") - } + fun candidateAliasFromRoomName(roomName: String, domain: String): String { + return roomName.lowercase() + .replaceSpaceChars(replacement = "_") + .removeInvalidRoomNameChars() + .take(MatrixConstants.maxAliasLocalPartLength(domain)) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixUrls.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixUrls.kt new file mode 100644 index 0000000000..dc4e0f152d --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixUrls.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2021 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 + +/** + * This class contains pattern to match Matrix Url, aka mxc urls + */ +object MatrixUrls { + const val MATRIX_CONTENT_URI_SCHEME = "mxc://" + + fun String.isMxcUrl() = startsWith(MATRIX_CONTENT_URI_SCHEME) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/UIABaseAuth.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/UIABaseAuth.kt index d5e323e457..3a8e6b1084 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/UIABaseAuth.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/UIABaseAuth.kt @@ -27,5 +27,5 @@ interface UIABaseAuth { fun copyWithSession(session: String): UIABaseAuth - fun asMap() : Map + fun asMap(): Map } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt index 3149a0218b..b2035bb2eb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt @@ -23,20 +23,20 @@ import java.io.IOException import javax.net.ssl.HttpsURLConnection fun Throwable.is401() = - this is Failure.ServerError - && httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */ - && error.code == MatrixError.M_UNAUTHORIZED + this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED && /* 401 */ + error.code == MatrixError.M_UNAUTHORIZED fun Throwable.isTokenError() = - this is Failure.ServerError - && (error.code == MatrixError.M_UNKNOWN_TOKEN - || error.code == MatrixError.M_MISSING_TOKEN - || error.code == MatrixError.ORG_MATRIX_EXPIRED_ACCOUNT) + this is Failure.ServerError && + (error.code == MatrixError.M_UNKNOWN_TOKEN || + error.code == MatrixError.M_MISSING_TOKEN || + error.code == MatrixError.ORG_MATRIX_EXPIRED_ACCOUNT) fun Throwable.shouldBeRetried(): Boolean { - return this is Failure.NetworkConnection - || this is IOException - || (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED) + return this is Failure.NetworkConnection || + this is IOException || + (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED) } /** @@ -52,31 +52,31 @@ fun Throwable.getRetryDelay(defaultValue: Long): Long { } fun Throwable.isInvalidPassword(): Boolean { - return this is Failure.ServerError - && error.code == MatrixError.M_FORBIDDEN - && error.message == "Invalid password" + return this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + error.message == "Invalid password" } fun Throwable.isInvalidUIAAuth(): Boolean { - return this is Failure.ServerError - && error.code == MatrixError.M_FORBIDDEN - && error.flows != null + return this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + error.flows != null } /** * Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible */ fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? { - return if (this is Failure.OtherServerError - && httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */) { + return if (this is Failure.OtherServerError && + httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */) { tryOrNull { MoshiProvider.providesMoshi() .adapter(RegistrationFlowResponse::class.java) .fromJson(errorBody) } - } else if (this is Failure.ServerError - && httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */ - && error.code == MatrixError.M_FORBIDDEN) { + } else if (this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED && /* 401 */ + error.code == MatrixError.M_FORBIDDEN) { // This happens when the submission for this stage was bad (like bad password) if (error.session != null && error.flows != null) { RegistrationFlowResponse( @@ -94,9 +94,9 @@ fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? { } fun Throwable.isRegistrationAvailabilityError(): Boolean { - return this is Failure.ServerError - && httpCode == HttpsURLConnection.HTTP_BAD_REQUEST /* 400 */ - && (error.code == MatrixError.M_USER_IN_USE - || error.code == MatrixError.M_INVALID_USERNAME - || error.code == MatrixError.M_EXCLUSIVE) + return this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_BAD_REQUEST && /* 400 */ + (error.code == MatrixError.M_USER_IN_USE || + error.code == MatrixError.M_INVALID_USERNAME || + error.code == MatrixError.M_EXCLUSIVE) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ApiPath.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ApiPath.kt index db112a30b2..baf33a59c5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ApiPath.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ApiPath.kt @@ -154,7 +154,6 @@ enum class ApiPath(val path: String, val method: String) { SEND_STATE_EVENT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state/{state_event_type}", "PUT"), SEND_STATE_EVENT_WITH_STATE_KEY(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state/{state_event_type}/{state_key}", "PUT"), GET_ROOM_STATE(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state", "GET"), - SEND_RELATION(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}", "POST"), GET_RELATIONS(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "rooms/{roomId}/relations/{eventId}/{relationType}/{eventType}", "GET"), JOIN_ROOM(NetworkConstants.URI_API_PREFIX_PATH_R0 + "join/{roomIdOrAlias}", "POST"), LEAVE_ROOM(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave", "POST"), diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index 1443a8d3b9..bde68da9d7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session import androidx.annotation.MainThread import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.SharedFlow import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.failure.GlobalError @@ -52,6 +53,7 @@ import org.matrix.android.sdk.api.session.signout.SignOutService import org.matrix.android.sdk.api.session.space.SpaceService import org.matrix.android.sdk.api.session.sync.FilterService import org.matrix.android.sdk.api.session.sync.SyncState +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.thirdparty.ThirdPartyService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker @@ -143,6 +145,11 @@ interface Session : */ fun getSyncState(): SyncState + /** + * This method returns a flow of SyncResponse. New value will be pushed through the sync thread. + */ + fun syncFlow(): SharedFlow + /** * This methods return true if an initial sync has been processed */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt index 47a63b4a25..ff1df63300 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallState.kt @@ -26,7 +26,7 @@ sealed class CallState { /** * CreateOffer. Intermediate state between Idle and Dialing. */ - object CreateOffer: CallState() + object CreateOffer : CallState() /** Dialing. Outgoing call is signaling the remote peer */ object Dialing : CallState() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt index 6327dd92fd..20ee68d228 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt @@ -24,8 +24,8 @@ data class MXCrossSigningInfo( val crossSigningKeys: List ) { - fun isTrusted(): Boolean = masterKey()?.trustLevel?.isVerified() == true - && selfSigningKey()?.trustLevel?.isVerified() == true + fun isTrusted(): Boolean = masterKey()?.trustLevel?.isVerified() == true && + selfSigningKey()?.trustLevel?.isVerified() == true fun masterKey(): CryptoCrossSigningKey? = crossSigningKeys .firstOrNull { it.usages?.contains(KeyUsage.MASTER.value) == true } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt index 810d28dd83..ba2d4ba3f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.api.session.crypto.keyshare -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingRequestCancellation +import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/PendingVerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/PendingVerificationRequest.kt index 1ee161724a..be450b9d03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/PendingVerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/PendingVerificationRequest.kt @@ -48,8 +48,8 @@ data class PendingVerificationRequest( * SAS is supported if I support it and the other party support it */ fun isSasSupported(): Boolean { - return requestInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() - && readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() + return requestInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() && + readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() } /** @@ -57,11 +57,11 @@ data class PendingVerificationRequest( */ fun otherCanShowQrCode(): Boolean { return if (isIncoming) { - requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() - && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() && + readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() } else { - requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() - && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() && + readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() } } @@ -70,11 +70,11 @@ data class PendingVerificationRequest( */ fun otherCanScanQrCode(): Boolean { return if (isIncoming) { - requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() - && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() && + readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() } else { - requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() - && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() && + readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 1f8471c111..96b44ce8c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -18,6 +18,9 @@ package org.matrix.android.sdk.api.session.events.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.json.JSONObject +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageType @@ -27,9 +30,6 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.di.MoshiProvider -import org.json.JSONObject -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.failure.MatrixError import timber.log.Timber typealias Content = JsonDict @@ -238,8 +238,8 @@ data class Event( } fun Event.isTextMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_TEXT, MessageType.MSGTYPE_EMOTE, MessageType.MSGTYPE_NOTICE -> true @@ -248,40 +248,40 @@ fun Event.isTextMessage(): Boolean { } fun Event.isImageMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_IMAGE -> true else -> false } } fun Event.isVideoMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_VIDEO -> true else -> false } } fun Event.isAudioMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_AUDIO -> true else -> false } } fun Event.isFileMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_FILE -> true else -> false } } fun Event.isAttachmentMessage(): Boolean { - return getClearType() == EventType.MESSAGE - && when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { + return getClearType() == EventType.MESSAGE && + when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { MessageType.MSGTYPE_IMAGE, MessageType.MSGTYPE_AUDIO, MessageType.MSGTYPE_VIDEO, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt index 9c3fdd57da..d0ce55070e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt @@ -106,13 +106,13 @@ object EventType { internal const val DUMMY = "m.dummy" fun isCallEvent(type: String): Boolean { - return type == CALL_INVITE - || type == CALL_CANDIDATES - || type == CALL_ANSWER - || type == CALL_HANGUP - || type == CALL_SELECT_ANSWER - || type == CALL_NEGOTIATE - || type == CALL_REJECT - || type == CALL_REPLACES + return type == CALL_INVITE || + type == CALL_CANDIDATES || + type == CALL_ANSWER || + type == CALL_HANGUP || + type == CALL_SELECT_ANSWER || + type == CALL_NEGOTIATE || + type == CALL_REJECT || + type == CALL_REPLACES } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt index b49236c338..3ed6a7ebb2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt @@ -89,7 +89,7 @@ data class HomeServerCapabilities( * You can also use #isFeatureSupported prior to this call to check if the * feature is supported and report some feedback to user. */ - fun versionOverrideForFeature(feature: String) : String? { + fun versionOverrideForFeature(feature: String): String? { val cap = roomVersions?.capabilities?.get(feature) return cap?.preferred ?: cap?.support?.lastOrNull() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt index 1485ec478b..a22cd572fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt @@ -132,7 +132,7 @@ interface IdentityService { * the identity server offers some crypto functionality to help in accepting invitations. * This is less secure than the client doing it itself, but may be useful where this isn't possible. */ - suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String) : SignInvitationResult + suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String): SignInvitationResult fun addListener(listener: IdentityServiceListener) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt index 38d47ae1a9..daab6d9761 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt @@ -25,7 +25,7 @@ interface SyncStatusService { /** * For initial sync */ - abstract class InitialSyncStatus: Status() + abstract class InitialSyncStatus : Status() object Idle : InitialSyncStatus() data class Progressing( @@ -36,7 +36,7 @@ interface SyncStatusService { /** * For incremental sync */ - abstract class IncrementalSyncStatus: Status() + abstract class IncrementalSyncStatus : Status() object IncrementalSyncIdle : IncrementalSyncStatus() data class IncrementalSyncParsing( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt index 5e9f3e1eb9..3e27da0c41 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt @@ -50,11 +50,11 @@ object MatrixLinkify { if (startPos == 0 || text[startPos - 1] != '/') { val endPos = match.range.last + 1 var url = text.substring(match.range) - if (MatrixPatterns.isUserId(url) - || MatrixPatterns.isRoomAlias(url) - || MatrixPatterns.isRoomId(url) - || MatrixPatterns.isGroupId(url) - || MatrixPatterns.isEventId(url)) { + if (MatrixPatterns.isUserId(url) || + MatrixPatterns.isRoomAlias(url) || + MatrixPatterns.isRoomId(url) || + MatrixPatterns.isGroupId(url) || + MatrixPatterns.isEventId(url)) { url = PermalinkService.MATRIX_TO_URL_BASE + url } val span = MatrixPermalinkSpan(url, callback) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt new file mode 100644 index 0000000000..a904e89681 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixToConverter.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2020 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.permalinks + +import android.net.Uri + +/** + * Mapping of an input URI to a matrix.to compliant URI. + */ +object MatrixToConverter { + + /** + * Try to convert a URL from an element web instance or from a client permalink to a matrix.to url. + * To be successfully converted, URL path should contain one of the [SUPPORTED_PATHS]. + * Examples: + * - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * - https://www.example.org/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + */ + fun convert(uri: Uri): Uri? { + val uriString = uri.toString() + + return when { + // URL is already a matrix.to + uriString.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> uri + // Web or client url + SUPPORTED_PATHS.any { it in uriString } -> { + val path = SUPPORTED_PATHS.first { it in uriString } + Uri.parse(PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path)) + } + // URL is not supported + else -> null + } + } + + private val SUPPORTED_PATHS = listOf( + "/#/room/", + "/#/user/", + "/#/group/" + ) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index 005a2edae7..edb748c76e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -26,6 +26,7 @@ import java.net.URLDecoder * This class turns a uri to a [PermalinkData] * element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks * or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org) + * or client permalinks (e.g. user/@chagai95:matrix.org) */ object PermalinkParser { @@ -42,13 +43,15 @@ object PermalinkParser { * https://github.com/matrix-org/matrix-doc/blob/master/proposals/1704-matrix.to-permalinks.md */ fun parse(uri: Uri): PermalinkData { - if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { - return PermalinkData.FallbackLink(uri) - } + // the client or element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the + // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid + // so convert URI to matrix.to to simplify parsing process + val matrixToUri = MatrixToConverter.convert(uri) ?: return PermalinkData.FallbackLink(uri) + // We can't use uri.fragment as it is decoding to early and it will break the parsing // of parameters that represents url (like signurl) - val fragment = uri.toString().substringAfter("#") // uri.fragment - if (fragment.isNullOrEmpty()) { + val fragment = matrixToUri.toString().substringAfter("#") // uri.fragment + if (fragment.isEmpty()) { return PermalinkData.FallbackLink(uri) } val safeFragment = fragment.substringBefore('?') @@ -61,20 +64,14 @@ object PermalinkParser { .map { URLDecoder.decode(it, "UTF-8") } .take(2) - // the element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the - // mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid - var identifier = params.getOrNull(0) - if (identifier.equals("user")) { - identifier = params.getOrNull(1) - } - + val identifier = params.getOrNull(0) val extraParameter = params.getOrNull(1) return when { identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri) MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier) MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier) MatrixPatterns.isRoomId(identifier) -> { - handleRoomIdCase(fragment, identifier, uri, extraParameter, viaQueryParameters) + handleRoomIdCase(fragment, identifier, matrixToUri, extraParameter, viaQueryParameters) } MatrixPatterns.isRoomAlias(identifier) -> { PermalinkData.RoomLink( @@ -125,12 +122,13 @@ object PermalinkParser { } } - private fun safeExtractParams(fragment: String) = fragment.substringAfter("?").split('&').mapNotNull { - val splitNameValue = it.split("=") - if (splitNameValue.size == 2) { - Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8")) - } else null - } + private fun safeExtractParams(fragment: String) = + fragment.substringAfter("?").split('&').mapNotNull { + val splitNameValue = it.split("=") + if (splitNameValue.size == 2) { + Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8")) + } else null + } private fun String.getViaParameters(): List { return UrlQuerySanitizer(this) @@ -138,9 +136,7 @@ object PermalinkParser { .filter { it.mParameter == "via" }.map { - it.mValue.let { - URLDecoder.decode(it, "UTF-8") - } + URLDecoder.decode(it.mValue, "UTF-8") } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index a6d4583c76..920dc85c7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -19,7 +19,8 @@ package org.matrix.android.sdk.api.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event /** - * Useful methods to create Matrix permalink (matrix.to links). + * Useful methods to create permalink (like matrix.to links or client permalinks). + * See [org.matrix.android.sdk.api.MatrixConfiguration.clientPermalinkBaseUrl] to setup a custom permalink base url. */ interface PermalinkService { @@ -32,10 +33,11 @@ interface PermalinkService { * Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org" * * @param event the event + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink, or null in case of error */ - fun createPermalink(event: Event): String? + fun createPermalink(event: Event, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for an id (can be a user Id, etc.). @@ -43,18 +45,21 @@ interface PermalinkService { * Ex: "https://matrix.to/#/@benoit:matrix.org" * * @param id the id + * @param forceMatrixTo whether we should force using matrix.to base URL + * * @return the permalink, or null in case of error */ - fun createPermalink(id: String): String? + fun createPermalink(id: String, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for a roomId, including the via parameters * * @param roomId the room id + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink, or null in case of error */ - fun createRoomPermalink(roomId: String, viaServers: List? = null): String? + fun createRoomPermalink(roomId: String, viaServers: List? = null, forceMatrixTo: Boolean = false): String? /** * Creates a permalink for an event. If you have an event you can use [createPermalink] @@ -62,10 +67,11 @@ interface PermalinkService { * * @param roomId the id of the room * @param eventId the id of the event + * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink */ - fun createPermalink(roomId: String, eventId: String): String + fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean = false): String /** * Extract the linked id from the universal link diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt index 6f607569c0..fff6adecbf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/AliasAvailabilityResult.kt @@ -19,6 +19,6 @@ package org.matrix.android.sdk.api.session.room import org.matrix.android.sdk.api.session.room.alias.RoomAliasError sealed class AliasAvailabilityResult { - object Available: AliasAvailabilityResult() + object Available : AliasAvailabilityResult() data class NotAvailable(val roomAliasError: RoomAliasError) : AliasAvailabilityResult() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt index f3e3913bc1..9446f0fdff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomDirectoryService.kt @@ -41,5 +41,5 @@ interface RoomDirectoryService { */ suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility) - suspend fun checkAliasAvailability(aliasLocalPart: String?) : AliasAvailabilityResult + suspend fun checkAliasAvailability(aliasLocalPart: String?): AliasAvailabilityResult } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index 5d26b21349..d80faa729c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -220,7 +220,7 @@ interface RoomService { .setPrefetchDistance(10) .build() - fun getFlattenRoomSummaryChildrenOf(spaceId: String?, memberships: List = Membership.activeMemberships()) : List + fun getFlattenRoomSummaryChildrenOf(spaceId: String?, memberships: List = Membership.activeMemberships()): List /** * Returns all the children of this space, as LiveData diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt index 180b32db05..6b4d782832 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallAnswerContent.kt @@ -44,7 +44,7 @@ data class CallAnswerContent( * Capability advertisement. */ @Json(name = "capabilities") val capabilities: CallCapabilities? = null -): CallSignalingContent { +) : CallSignalingContent { @JsonClass(generateAdapter = true) data class Answer( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt index dc0a1e3b2e..deec80f4ff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallCandidatesContent.kt @@ -41,4 +41,4 @@ data class CallCandidatesContent( * Required. The version of the VoIP specification this messages adheres to. */ @Json(name = "version") override val version: String? -): CallSignalingContent +) : CallSignalingContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt index e4332f0ea7..d70e63d122 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallInviteContent.kt @@ -55,7 +55,7 @@ data class CallInviteContent( */ @Json(name = "capabilities") val capabilities: CallCapabilities? = null -): CallSignalingContent { +) : CallSignalingContent { @JsonClass(generateAdapter = true) data class Offer( /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt index 68dd5ef043..bbbfbe68ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallNegotiateContent.kt @@ -47,7 +47,7 @@ data class CallNegotiateContent( */ @Json(name = "version") override val version: String? - ): CallSignalingContent { + ) : CallSignalingContent { @JsonClass(generateAdapter = true) data class Description( /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt index 4559c5db6d..7947b7d0bd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallReplacesContent.kt @@ -61,7 +61,7 @@ data class CallReplacesContent( * Required. The version of the VoIP specification this messages adheres to. */ @Json(name = "version") override val version: String? -): CallSignalingContent { +) : CallSignalingContent { @JsonClass(generateAdapter = true) data class TargetUser( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt index 795f332711..634bee1d83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/call/CallSelectAnswerContent.kt @@ -41,4 +41,4 @@ data class CallSelectAnswerContent( * Required. The version of the VoIP specification this message adheres to. */ @Json(name = "version") override val version: String? -): CallSignalingContent +) : CallSignalingContent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt index ea67b55174..d806e6007e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/version/RoomVersionService.kt @@ -31,7 +31,7 @@ interface RoomVersionService { /** * Get the recommended room version for the current homeserver */ - fun getRecommendedVersion() : String + fun getRecommendedVersion(): String /** * Ask if the user has enough power level to upgrade the room diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageError.kt index 59325f9903..a91b97b86c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageError.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageError.kt @@ -22,8 +22,8 @@ sealed class SharedSecretStorageError(message: String?) : Throwable(message) { data class UnknownAlgorithm(val keyId: String) : SharedSecretStorageError("Unknown algorithm $keyId") data class UnsupportedAlgorithm(val algorithm: String) : SharedSecretStorageError("Unknown algorithm $algorithm") data class SecretNotEncrypted(val secretName: String) : SharedSecretStorageError("Missing content for secret $secretName") - data class SecretNotEncryptedWithKey(val secretName: String, val keyId: String) - : SharedSecretStorageError("Missing content for secret $secretName with key $keyId") + data class SecretNotEncryptedWithKey(val secretName: String, val keyId: String) : + SharedSecretStorageError("Missing content for secret $secretName with key $keyId") object BadKeyFormat : SharedSecretStorageError("Bad Key Format") object ParsingError : SharedSecretStorageError("parsing Error") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt index bfa8c342b6..c05e1e5187 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceListResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceListResponse.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass @@ -21,7 +22,7 @@ import com.squareup.moshi.JsonClass * This class describes the device list response from a sync request */ @JsonClass(generateAdapter = true) -internal data class DeviceListResponse( +data class DeviceListResponse( // user ids list which have new crypto devices val changed: List = emptyList(), // List of user ids who are no more tracked. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt similarity index 87% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt index d5b435ac27..930cfb153f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/DeviceOneTimeKeysCountSyncResponse.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class DeviceOneTimeKeysCountSyncResponse( +data class DeviceOneTimeKeysCountSyncResponse( @Json(name = "signed_curve25519") val signedCurve25519: Int? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt index ee6aabb0a9..581e6824ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupSyncProfile.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupSyncProfile.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class GroupSyncProfile( +data class GroupSyncProfile( /** * The name of the group, if any. May be nil. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt index 4c2dce3ba8..fd8710bbda 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/GroupsSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/GroupsSyncResponse.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class GroupsSyncResponse( +data class GroupsSyncResponse( /** * Joined groups: An array of groups ids. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt index 148c2aeab9..d41df9f0f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedGroupSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedGroupSync.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class InvitedGroupSync( +data class InvitedGroupSync( /** * The identifier of the inviter. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt index c21a73abc2..dc63c5ba07 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/InvitedRoomSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/InvitedRoomSync.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // InvitedRoomSync represents a room invitation during server sync v2. @JsonClass(generateAdapter = true) -internal data class InvitedRoomSync( +data class InvitedRoomSync( /** * The state of a room that the user has been invited to. These state events may only have the 'sender', 'type', 'state_key' diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt similarity index 77% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt index 83006c646b..087a5f52dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/LazyRoomSyncEphemeral.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/LazyRoomSyncEphemeral.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * Copyright 2020 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 + * 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, @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = false) -internal sealed class LazyRoomSyncEphemeral { +sealed class LazyRoomSyncEphemeral { data class Parsed(val _roomSyncEphemeral: RoomSyncEphemeral) : LazyRoomSyncEphemeral() object Stored : LazyRoomSyncEphemeral() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt index 92d09aa4f5..d632552888 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/PresenceSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/PresenceSyncResponse.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event // PresenceSyncResponse represents the updates to the presence status of other users during server sync v2. @JsonClass(generateAdapter = true) -internal data class PresenceSyncResponse( +data class PresenceSyncResponse( /** * List of presence events (array of Event with type m.presence). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt index ded9e2a350..59b4b4fc32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomInviteState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomInviteState.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -21,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomInviteState represents the state of a room that the user has been invited to. @JsonClass(generateAdapter = true) -internal data class RoomInviteState( +data class RoomInviteState( /** * List of state events (array of MXEvent). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt index 9aed0d37d6..e3d07602c7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSync.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // RoomSync represents the response for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSync( +data class RoomSync( /** * The state updates for the room. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt index a2375507d8..f2c4ed551c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncAccountData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncAccountData.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event @JsonClass(generateAdapter = true) -internal data class RoomSyncAccountData( +data class RoomSyncAccountData( /** * List of account data events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt index f2135db6b7..f4d831c16f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncEphemeral.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncEphemeral.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncEphemeral represents the ephemeral events in the room that aren't recorded in the timeline or state of the room (e.g. typing). @JsonClass(generateAdapter = true) -internal data class RoomSyncEphemeral( +data class RoomSyncEphemeral( /** * List of ephemeral events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt index f86f05d000..7822467564 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncState.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncState represents the state updates for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSyncState( +data class RoomSyncState( /** * List of state events (array of Event). The resulting state corresponds to the *start* of the timeline. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt index 228a71ec28..7216a0c992 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncSummary.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -internal data class RoomSyncSummary( +data class RoomSyncSummary( /** * Present only if the room has no m.room.name or m.room.canonical_alias. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt index 27bbc4343f..82d29a52e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncTimeline.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event // RoomSyncTimeline represents the timeline of messages and state changes for a room during server sync v2. @JsonClass(generateAdapter = true) -internal data class RoomSyncTimeline( +data class RoomSyncTimeline( /** * List of events (array of Event). diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt index f01534b884..6618bceacd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomSyncUnreadNotifications.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomSyncUnreadNotifications.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.Event * `MXRoomSyncUnreadNotifications` represents the unread counts for a room. */ @JsonClass(generateAdapter = true) -internal data class RoomSyncUnreadNotifications( +data class RoomSyncUnreadNotifications( /** * List of account data events (array of Event). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt index dd2f96c988..ff3ed54264 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/RoomsSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/RoomsSyncResponse.kt @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model + +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass // RoomsSyncResponse represents the rooms list in server sync v2 response. @JsonClass(generateAdapter = true) -internal data class RoomsSyncResponse( +data class RoomsSyncResponse( /** * Joined rooms: keys are rooms ids. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt index f2b2fb7e8f..876e99da63 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/SyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/SyncResponse.kt @@ -14,15 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.session.sync.model.accountdata.UserAccountDataSync // SyncResponse represents the request response for server sync v2. @JsonClass(generateAdapter = true) -internal data class SyncResponse( +data class SyncResponse( /** * The user private data. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt index 8f3af56cde..082460cc2d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/ToDeviceSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/ToDeviceSyncResponse.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Event // ToDeviceSyncResponse represents the data directly sent to one of user's devices. @JsonClass(generateAdapter = true) -internal data class ToDeviceSyncResponse( +data class ToDeviceSyncResponse( /** * List of direct-to-device events. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/UserAccountDataSync.kt similarity index 88% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/UserAccountDataSync.kt index 05b50ab2c5..9e1b791919 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/UserAccountDataSync.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/model/UserAccountDataSync.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.model.accountdata +package org.matrix.android.sdk.api.session.sync.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent @JsonClass(generateAdapter = true) -internal data class UserAccountDataSync( +data class UserAccountDataSync( @Json(name = "events") val list: List = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt index 7cd939a5c2..54ae9e54f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt @@ -23,13 +23,8 @@ package org.matrix.android.sdk.api.session.user.model data class User( val userId: String, /** - * For usage in UI, consider using [getBestName] + * For usage in UI, consider converting to MatrixItem and call getBestName() */ val displayName: String? = null, val avatarUrl: String? = null -) { - /** - * Return the display name or the user id - */ - fun getBestName() = displayName?.takeIf { it.isNotEmpty() } ?: userId -} +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 3d2773fb4b..3396c4a6c9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -34,8 +34,8 @@ sealed class MatrixItem( ) { data class UserItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName?.removeSuffix(ircPattern), avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName?.removeSuffix(ircPattern), avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -45,8 +45,8 @@ sealed class MatrixItem( data class EventItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName, avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -56,8 +56,8 @@ sealed class MatrixItem( data class RoomItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName, avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -67,8 +67,8 @@ sealed class MatrixItem( data class SpaceItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName, avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -78,36 +78,26 @@ sealed class MatrixItem( data class RoomAliasItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName, avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } - // Best name is the id, and we keep the displayName of the room for the case we need the first letter - override fun getBestName() = id - override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } data class GroupItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) - : MatrixItem(id, displayName, avatarUrl) { + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } - // Best name is the id, and we keep the displayName of the room for the case we need the first letter - override fun getBestName() = id - override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } - open fun getBestName(): String { - return displayName?.takeIf { it.isNotBlank() } ?: id - } - protected fun checkId() { if (!id.startsWith(getIdPrefix())) { error("Wrong usage of MatrixItem: check the id $id should start with ${getIdPrefix()}") 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 e76dc28734..641a8f1bb6 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 @@ -172,8 +172,8 @@ internal class DefaultAuthenticationService @Inject constructor( return try { getWellknownLoginFlowInternal(homeServerConnectionConfig) } catch (failure: Throwable) { - if (failure is Failure.OtherServerError - && failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { + if (failure is Failure.OtherServerError && + failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { // 404, no well-known data, try direct access to the API // First check the homeserver version return runCatching { @@ -190,8 +190,8 @@ internal class DefaultAuthenticationService @Inject constructor( it }, { - if (it is Failure.OtherServerError - && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { + if (it is Failure.OtherServerError && + it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { // It's maybe a Web client url? getWebClientDomainLoginFlowInternal(homeServerConnectionConfig) } else { @@ -225,8 +225,8 @@ internal class DefaultAuthenticationService @Inject constructor( it }, { - if (it is Failure.OtherServerError - && it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { + if (it is Failure.OtherServerError && + it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { // Try with config.json getWebClientLoginFlowInternal(homeServerConnectionConfig) } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt index bc3d887000..94b301649f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/IsValidClientServerApiTask.kt @@ -54,8 +54,8 @@ internal class DefaultIsValidClientServerApiTask @Inject constructor( // We get a response, so the API is valid true } catch (failure: Throwable) { - if (failure is Failure.OtherServerError - && failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { + if (failure is Failure.OtherServerError && + failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) { // Probably not valid false } else { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmPendingSessionStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmPendingSessionStore.kt index 968ae22eda..13f26e321d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmPendingSessionStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmPendingSessionStore.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.auth.db +import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.auth.PendingSessionStore import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.di.AuthDatabase -import io.realm.Realm -import io.realm.RealmConfiguration import javax.inject.Inject internal class RealmPendingSessionStore @Inject constructor(private val mapper: PendingSessionMapper, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmSessionParamsStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmSessionParamsStore.kt index edd3e2bed5..235ef6b709 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmSessionParamsStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/RealmSessionParamsStore.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.auth.db +import io.realm.Realm +import io.realm.RealmConfiguration +import io.realm.exceptions.RealmPrimaryKeyConstraintException import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.auth.data.sessionId import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.di.AuthDatabase -import io.realm.Realm -import io.realm.RealmConfiguration -import io.realm.exceptions.RealmPrimaryKeyConstraintException import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt index 3888633723..8f61afe374 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.auth.login import dagger.Lazy +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session @@ -29,7 +30,6 @@ import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.network.httpclient.addSocketFactory import org.matrix.android.sdk.internal.network.ssl.UnrecognizedCertificateException import org.matrix.android.sdk.internal.task.Task -import okhttp3.OkHttpClient import javax.inject.Inject internal interface DirectLoginTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt index 4e599516ed..74cb3de2ac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt @@ -63,9 +63,9 @@ internal fun Versions.isSupportedBySdk(): Boolean { * Return true if the SDK supports this homeserver version for login and registration */ internal fun Versions.isLoginAndRegistrationSupportedBySdk(): Boolean { - return !doesServerRequireIdentityServerParam() - && doesServerAcceptIdentityAccessToken() - && doesServerSeparatesAddAndBind() + return !doesServerRequireIdentityServerParam() && + doesServerAcceptIdentityAccessToken() && + doesServerSeparatesAddAndBind() } /** @@ -74,8 +74,8 @@ internal fun Versions.isLoginAndRegistrationSupportedBySdk(): Boolean { * @return true if the server support the lazy loading of room members */ private fun Versions.supportLazyLoadMembers(): Boolean { - return getMaxVersion() >= HomeServerVersion.r0_5_0 - || unstableFeatures?.get(FEATURE_LAZY_LOAD_MEMBERS) == true + return getMaxVersion() >= HomeServerVersion.r0_5_0 || + unstableFeatures?.get(FEATURE_LAZY_LOAD_MEMBERS) == true } /** @@ -92,13 +92,13 @@ private fun Versions.doesServerRequireIdentityServerParam(): Boolean { * Some homeservers may trigger errors if they are not prepared for the new parameter. */ private fun Versions.doesServerAcceptIdentityAccessToken(): Boolean { - return getMaxVersion() >= HomeServerVersion.r0_6_0 - || unstableFeatures?.get(FEATURE_ID_ACCESS_TOKEN) ?: false + return getMaxVersion() >= HomeServerVersion.r0_6_0 || + unstableFeatures?.get(FEATURE_ID_ACCESS_TOKEN) ?: false } private fun Versions.doesServerSeparatesAddAndBind(): Boolean { - return getMaxVersion() >= HomeServerVersion.r0_6_0 - || unstableFeatures?.get(FEATURE_SEPARATE_ADD_AND_BIND) ?: false + return getMaxVersion() >= HomeServerVersion.r0_6_0 || + unstableFeatures?.get(FEATURE_SEPARATE_ADD_AND_BIND) ?: false } private fun Versions.getMaxVersion(): HomeServerVersion { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt index 0ec020bc46..c11d00278b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt @@ -35,8 +35,8 @@ import org.matrix.android.sdk.internal.worker.SessionWorkerParams import javax.inject.Inject internal class CancelGossipRequestWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index 84d4fef5af..fe388b44e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -19,6 +19,9 @@ package org.matrix.android.sdk.internal.crypto import dagger.Binds import dagger.Module import dagger.Provides +import io.realm.RealmConfiguration +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.internal.crypto.api.CryptoApi @@ -93,9 +96,6 @@ import org.matrix.android.sdk.internal.di.UserMd5 import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.cache.ClearCacheTask import org.matrix.android.sdk.internal.session.cache.RealmClearCacheTask -import io.realm.RealmConfiguration -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob import retrofit2.Retrofit import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 563c890950..7115ff5db2 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -50,6 +50,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting @@ -87,7 +88,6 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith @@ -868,8 +868,8 @@ internal class DefaultCryptoService @Inject constructor( } private fun getRoomUserIds(roomId: String): List { - val encryptForInvitedMembers = isEncryptionEnabledForInvitedUser() - && shouldEncryptForInvitedMembers(roomId) + val encryptForInvitedMembers = isEncryptionEnabledForInvitedUser() && + shouldEncryptForInvitedMembers(roomId) return cryptoSessionInfoProvider.getRoomUserIds(roomId, encryptForInvitedMembers) } @@ -887,9 +887,9 @@ internal class DefaultCryptoService @Inject constructor( if (membership == Membership.JOIN) { // make sure we are tracking the deviceList for this user. deviceListManager.startTrackingDeviceList(listOf(userId)) - } else if (membership == Membership.INVITE - && shouldEncryptForInvitedMembers(roomId) - && isEncryptionEnabledForInvitedUser()) { + } else if (membership == Membership.INVITE && + shouldEncryptForInvitedMembers(roomId) && + isEncryptionEnabledForInvitedUser()) { // track the deviceList for this invited user. // Caution: there's a big edge case here in that federated servers do not // know what other servers are in the room at the time they've been invited. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index 79910c6de2..8a91376b60 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -475,8 +475,8 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM } if (!isVerified) { - Timber.e("## CRYPTO | validateDeviceKeys() : Unable to verify signature on device " + userId + ":" - + deviceKeys.deviceId + " with error " + errorMessage) + Timber.e("## CRYPTO | validateDeviceKeys() : Unable to verify signature on device " + userId + ":" + + deviceKeys.deviceId + " with error " + errorMessage) return false } @@ -486,9 +486,9 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM // best off sticking with the original keys. // // Should we warn the user about it somehow? - Timber.e("## CRYPTO | validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":" - + deviceKeys.deviceId + " has changed : " - + previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey) + Timber.e("## CRYPTO | validateDeviceKeys() : WARNING:Ed25519 key for device " + userId + ":" + + deviceKeys.deviceId + " has changed : " + + previouslyStoredDeviceKeys.fingerprint() + " -> " + signKey) Timber.e("## CRYPTO | validateDeviceKeys() : $previouslyStoredDeviceKeys -> $deviceKeys") Timber.e("## CRYPTO | validateDeviceKeys() : ${previouslyStoredDeviceKeys.keys} -> ${deviceKeys.keys}") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index 8d86380e39..fe17dd08e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -107,8 +107,8 @@ internal class EventDecryptor @Inject constructor( } catch (mxCryptoError: MXCryptoError) { Timber.v("## CRYPTO | internalDecryptEvent : Failed to decrypt ${event.eventId} reason: $mxCryptoError") if (algorithm == MXCRYPTO_ALGORITHM_OLM) { - if (mxCryptoError is MXCryptoError.Base - && mxCryptoError.errorType == MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE) { + if (mxCryptoError is MXCryptoError.Base && + mxCryptoError.errorType == MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE) { // need to find sending device cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { val olmContent = event.content.toModel() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt index ccdb5ab137..6fc7103668 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt @@ -16,17 +16,17 @@ package org.matrix.android.sdk.internal.crypto +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId +import org.matrix.android.sdk.internal.crypto.util.RequestIdHelper import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.worker.WorkerParamsFactory -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId -import org.matrix.android.sdk.internal.crypto.util.RequestIdHelper import timber.log.Timber import javax.inject.Inject @@ -112,9 +112,8 @@ internal class OutgoingGossipingRequestManager @Inject constructor( * @param andResend true to resend the key request */ private fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody, andResend: Boolean) { - val req = cryptoStore.getOutgoingRoomKeyRequest(requestBody) - ?: // no request was made for this key - return Unit.also { + val req = cryptoStore.getOutgoingRoomKeyRequest(requestBody) // no request was made for this key + ?: return Unit.also { Timber.v("## CRYPTO - GOSSIP cancelRoomKeyRequest() Unknown request $requestBody") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt index 2e26720abb..b2ba189b65 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt @@ -38,8 +38,8 @@ import timber.log.Timber import javax.inject.Inject internal class SendGossipRequestWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt index c5c6d26f79..b96943e4ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt @@ -38,8 +38,8 @@ import timber.log.Timber import javax.inject.Inject internal class SendGossipWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt index 95b99c54e8..52876b0fff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt @@ -90,8 +90,8 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor( oneTimeKey = key } if (oneTimeKey == null) { - Timber.w("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm - + " for device " + userId + " : " + deviceId) + Timber.w("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm + + " for device " + userId + " : " + deviceId) continue } // Update the result for this device in results @@ -126,15 +126,15 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor( sessionId = olmDevice.createOutboundSession(deviceInfo.identityKey()!!, oneTimeKey.value) if (!sessionId.isNullOrEmpty()) { - Timber.v("## CRYPTO | verifyKeyAndStartSession() : Started new sessionid " + sessionId - + " for device " + deviceInfo + "(theirOneTimeKey: " + oneTimeKey.value + ")") + Timber.v("## CRYPTO | verifyKeyAndStartSession() : Started new sessionid " + sessionId + + " for device " + deviceInfo + "(theirOneTimeKey: " + oneTimeKey.value + ")") } else { // Possibly a bad key Timber.e("## CRYPTO | verifyKeyAndStartSession() : Error starting session with device $userId:$deviceId") } } else { - Timber.e("## CRYPTO | verifyKeyAndStartSession() : Unable to verify signature on one-time key for device " + userId - + ":" + deviceId + " Error " + errorMessage) + Timber.e("## CRYPTO | verifyKeyAndStartSession() : Unable to verify signature on one-time key for device " + userId + + ":" + deviceId + " Error " + errorMessage) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt index a276394eaf..a3cfbd91f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt @@ -38,9 +38,9 @@ internal class EnsureOlmSessionsForUsersAction @Inject constructor(private val o devices.filter { // Don't bother setting up session to ourself - it.identityKey() != olmDevice.deviceCurve25519Key + it.identityKey() != olmDevice.deviceCurve25519Key && // Don't bother setting up sessions with blocked users - && !(it.trustLevel?.isVerified() ?: false) + !(it.trustLevel?.isVerified() ?: false) } } return ensureOlmSessionsForDevicesAction.handle(devicesByUser) 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 70d2022299..d2f6bd0382 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 @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -40,8 +42,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import timber.log.Timber internal class MXMegolmDecryption(private val userId: String, @@ -82,9 +82,9 @@ internal class MXMegolmDecryption(private val userId: String, val encryptedEventContent = event.content.toModel() ?: throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) - if (encryptedEventContent.senderKey.isNullOrBlank() - || encryptedEventContent.sessionId.isNullOrBlank() - || encryptedEventContent.ciphertext.isNullOrBlank()) { + if (encryptedEventContent.senderKey.isNullOrBlank() || + encryptedEventContent.sessionId.isNullOrBlank() || + encryptedEventContent.ciphertext.isNullOrBlank()) { throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryptionFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryptionFactory.kt index 95a4342dbf..91640523fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryptionFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryptionFactory.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm +import kotlinx.coroutines.CoroutineScope import org.matrix.android.sdk.internal.crypto.DeviceListManager import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager @@ -25,7 +26,6 @@ import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.CoroutineScope import javax.inject.Inject internal class MXMegolmDecryptionFactory @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index 540280d8a2..63fe678229 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -155,11 +155,11 @@ internal class MXMegolmEncryption( private suspend fun ensureOutboundSession(devicesInRoom: MXUsersDevicesMap): MXOutboundSessionInfo { Timber.v("## CRYPTO | ensureOutboundSession start") var session = outboundSession - if (session == null + if (session == null || // Need to make a brand new session? - || session.needsRotation(sessionRotationPeriodMsgs, sessionRotationPeriodMs) + session.needsRotation(sessionRotationPeriodMsgs, sessionRotationPeriodMs) || // Determine if we have shared with anyone we shouldn't have - || session.sharedWithTooManyDevices(devicesInRoom)) { + session.sharedWithTooManyDevices(devicesInRoom)) { session = prepareNewSessionInRoom() outboundSession = session } @@ -380,8 +380,8 @@ internal class MXMegolmEncryption( // with them, which means that they will have announced any new devices via // an m.new_device. val keys = deviceListManager.downloadKeys(userIds, false) - val encryptToVerifiedDevicesOnly = cryptoStore.getGlobalBlacklistUnverifiedDevices() - || cryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(roomId) + val encryptToVerifiedDevicesOnly = cryptoStore.getGlobalBlacklistUnverifiedDevices() || + cryptoStore.getRoomsListBlacklistUnverifiedDevices().contains(roomId) val devicesInRoom = DeviceInRoomInfo() val unknownDevices = MXUsersDevicesMap() @@ -446,10 +446,9 @@ internal class MXMegolmEncryption( val devicesByUser = mapOf(userId to listOf(deviceInfo)) val usersDeviceMap = ensureOlmSessionsForDevicesAction.handle(devicesByUser) val olmSessionResult = usersDeviceMap.getObject(userId, deviceId) - olmSessionResult?.sessionId - ?: // no session with this device, probably because there were no one-time keys. + olmSessionResult?.sessionId // no session with this device, probably because there were no one-time keys. // ensureOlmSessionsForDevicesAction has already done the logging, so just skip it. - return false.also { + ?: return false.also { Timber.w("## Crypto reshareKey: no session with this device, probably because there were no one-time keys") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 082b86c9da..f1bca4fbc6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -34,8 +34,8 @@ internal class MXOlmDecryption( // The olm device interface private val olmDevice: MXOlmDevice, // the matrix userId - private val userId: String) - : IMXDecrypting { + private val userId: String) : + IMXDecrypting { @Throws(MXCryptoError::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt index 65f78e11f0..63f2533ac3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt @@ -32,8 +32,8 @@ internal class MXOlmEncryption( private val cryptoStore: IMXCryptoStore, private val messageEncrypter: MessageEncrypter, private val deviceListManager: DeviceListManager, - private val ensureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction) - : IMXEncrypting { + private val ensureOlmSessionsForUsersAction: EnsureOlmSessionsForUsersAction) : + IMXEncrypting { override suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List): Content { // pick the list of recipients based on the membership list. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt index c071384df4..3d00e178a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.crypto.attachments import android.os.Parcelable -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo import kotlinx.parcelize.Parcelize +import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? { // Check the validity of some fields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt index ee5aab977b..113255bb7e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt @@ -15,6 +15,7 @@ */ package org.matrix.android.sdk.internal.crypto.crosssigning +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo @@ -22,7 +23,6 @@ import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.withContext import javax.inject.Inject internal interface ComputeTrustTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt index 0289fadbd8..8a851b1267 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt @@ -529,13 +529,13 @@ internal class DefaultCrossSigningService @Inject constructor( } override fun canCrossSign(): Boolean { - return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null - && cryptoStore.getCrossSigningPrivateKeys()?.user != null + return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null && + cryptoStore.getCrossSigningPrivateKeys()?.user != null } override fun allPrivateKeysKnown(): Boolean { - return checkSelfTrust().isVerified() - && cryptoStore.getCrossSigningPrivateKeys()?.allKnown().orFalse() + return checkSelfTrust().isVerified() && + cryptoStore.getCrossSigningPrivateKeys()?.allKnown().orFalse() } override fun trustUser(otherUserId: String, callback: MatrixCallback) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt index 76b63b7798..3326d3707a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt @@ -51,8 +51,8 @@ import timber.log.Timber import javax.inject.Inject internal class UpdateTrustWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( 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 fbcf5cfdeb..c6e2c1217f 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 @@ -21,6 +21,10 @@ import android.os.Looper import androidx.annotation.UiThread import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.Failure @@ -40,6 +44,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo +import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData @@ -80,11 +85,6 @@ import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.awaitCallback -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.olm.OlmException import org.matrix.olm.OlmPkDecryption import org.matrix.olm.OlmPkEncryption @@ -860,8 +860,8 @@ internal class DefaultKeysBackupService @Inject constructor( } override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError - && failure.error.code == MatrixError.M_NOT_FOUND) { + if (failure is Failure.ServerError && + failure.error.code == MatrixError.M_NOT_FOUND) { // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup callback.onSuccess(null) } else { @@ -883,8 +883,8 @@ internal class DefaultKeysBackupService @Inject constructor( } override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError - && failure.error.code == MatrixError.M_NOT_FOUND) { + if (failure is Failure.ServerError && + failure.error.code == MatrixError.M_NOT_FOUND) { // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup callback.onSuccess(null) } else { @@ -1042,8 +1042,8 @@ internal class DefaultKeysBackupService @Inject constructor( return null } - if (authData.privateKeySalt.isNullOrBlank() - || authData.privateKeyIterations == null) { + if (authData.privateKeySalt.isNullOrBlank() || + authData.privateKeyIterations == null) { Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") return null 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 7c0c741a2c..78ef958bbf 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 @@ -44,16 +44,16 @@ internal class KeysBackupStateManager(private val uiHandler: Handler) { } val isEnabled: Boolean - get() = state == KeysBackupState.ReadyToBackUp - || state == KeysBackupState.WillBackUp - || state == KeysBackupState.BackingUp + get() = state == KeysBackupState.ReadyToBackUp || + state == KeysBackupState.WillBackUp || + state == KeysBackupState.BackingUp // True if unknown or bad state val isStucked: Boolean - get() = state == KeysBackupState.Unknown - || state == KeysBackupState.Disabled - || state == KeysBackupState.WrongBackUpVersion - || state == KeysBackupState.NotTrusted + get() = state == KeysBackupState.Unknown || + state == KeysBackupState.Disabled || + state == KeysBackupState.WrongBackUpVersion || + state == KeysBackupState.NotTrusted fun addListener(listener: KeysBackupStateListener) { synchronized(listeners) { 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 fb10cf4482..ad3bc012df 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 @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto.secrets +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService @@ -43,8 +45,6 @@ import org.matrix.android.sdk.internal.crypto.tools.HkdfSha256 import org.matrix.android.sdk.internal.crypto.tools.withOlmDecryption import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.withContext import org.matrix.olm.OlmPkMessage import java.security.SecureRandom import javax.crypto.Cipher @@ -359,8 +359,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor( val keyInfo = (keyInfoResult as? KeyInfoResult.Success)?.keyInfo ?: return IntegrityResult.Error(SharedSecretStorageError.UnknownKey(keyId ?: "")) - if (keyInfo.content.algorithm != SSSS_ALGORITHM_AES_HMAC_SHA2 - && keyInfo.content.algorithm != SSSS_ALGORITHM_CURVE25519_AES_SHA2) { + if (keyInfo.content.algorithm != SSSS_ALGORITHM_AES_HMAC_SHA2 && + keyInfo.content.algorithm != SSSS_ALGORITHM_CURVE25519_AES_SHA2) { // Unsupported algorithm return IntegrityResult.Error( SharedSecretStorageError.UnsupportedAlgorithm(keyInfo.content.algorithm ?: "") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 860bba7404..3c8f74d419 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -152,8 +152,8 @@ internal class RealmCryptoStore @Inject constructor( // Check credentials // The device id may not have been provided in credentials. // Check it only if provided, else trust the stored one. - if (currentMetadata.userId != userId - || (deviceId != null && deviceId != currentMetadata.deviceId)) { + if (currentMetadata.userId != userId || + (deviceId != null && deviceId != currentMetadata.deviceId)) { Timber.w("## open() : Credentials do not match, close this store and delete data") deleteAll = true currentMetadata = null @@ -178,9 +178,9 @@ internal class RealmCryptoStore @Inject constructor( override fun hasData(): Boolean { return doWithRealm(realmConfiguration) { - !it.isEmpty + !it.isEmpty && // Check if there is a MetaData object - && it.where().count() > 0 + it.where().count() > 0 } } @@ -1025,10 +1025,10 @@ internal class RealmCryptoStore @Inject constructor( }.mapNotNull { it.toOutgoingGossipingRequest() as? OutgoingRoomKeyRequest }.firstOrNull { - it.requestBody?.algorithm == requestBody.algorithm - && it.requestBody?.roomId == requestBody.roomId - && it.requestBody?.senderKey == requestBody.senderKey - && it.requestBody?.sessionId == requestBody.sessionId + it.requestBody?.algorithm == requestBody.algorithm && + it.requestBody?.roomId == requestBody.roomId && + it.requestBody?.senderKey == requestBody.senderKey && + it.requestBody?.sessionId == requestBody.sessionId } } @@ -1113,10 +1113,10 @@ internal class RealmCryptoStore @Inject constructor( .mapNotNull { it.toOutgoingGossipingRequest() as? OutgoingRoomKeyRequest }.firstOrNull { - it.requestBody?.algorithm == requestBody.algorithm - && it.requestBody?.sessionId == requestBody.sessionId - && it.requestBody?.senderKey == requestBody.senderKey - && it.requestBody?.roomId == requestBody.roomId + it.requestBody?.algorithm == requestBody.algorithm && + it.requestBody?.sessionId == requestBody.sessionId && + it.requestBody?.senderKey == requestBody.senderKey && + it.requestBody?.roomId == requestBody.roomId } if (existing == null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt index 6aae68c83e..a2f2f8e97a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreModule.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.store.db +import io.realm.annotations.RealmModule import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity @@ -27,13 +28,12 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntit import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntity import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity -import io.realm.annotations.RealmModule -import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntity /** * Realm module for Crypto store classes diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt index 9e73985592..c15414a8dd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.crypto.store.db.mapper import com.squareup.moshi.Moshi import com.squareup.moshi.Types +import io.realm.RealmList import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntity -import io.realm.RealmList import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt index 5166f6c31f..35ae86db8b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMetadataEntity.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.crypto.store.db.model -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm import org.matrix.olm.OlmAccount internal open class CryptoMetadataEntity( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt index e226f3eaa8..711b698464 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt @@ -28,8 +28,8 @@ internal open class CryptoRoomEntity( // to avoid re-create and re-share at each startup (if rotation not needed..) // This is specific to megolm but not sure how to model it better var outboundSessionInfo: OutboundGroupSessionInfoEntity? = null - ) - : RealmObject() { + ) : + RealmObject() { companion object } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt index b8675d0823..75094f01db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt @@ -17,6 +17,8 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import com.squareup.moshi.JsonDataException +import io.realm.RealmObject +import io.realm.annotations.Index import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState @@ -24,8 +26,6 @@ import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.di.MoshiProvider -import io.realm.RealmObject -import io.realm.annotations.Index import timber.log.Timber /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt index df45568d18..4457a44cb2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto.store.db.model +import io.realm.RealmObject +import io.realm.annotations.Index import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.internal.crypto.GossipRequestType import org.matrix.android.sdk.internal.crypto.GossipingRequestState @@ -23,8 +25,6 @@ import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody -import io.realm.RealmObject -import io.realm.annotations.Index internal open class IncomingGossipingRequestEntity(@Index var requestId: String? = "", @Index var typeStr: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt index d0e16bbe11..f330e8822a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmInboundGroupSessionEntity.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.store.db.model +import io.realm.RealmObject +import io.realm.annotations.PrimaryKey import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey import timber.log.Timber internal fun OlmInboundGroupSessionEntity.Companion.createPrimaryKey(sessionId: String?, senderKey: String?) = "$sessionId|$senderKey" @@ -33,8 +33,8 @@ internal open class OlmInboundGroupSessionEntity( // olmInboundGroupSessionData contains Json var olmInboundGroupSessionData: String? = null, // Indicate if the key has been backed up to the homeserver - var backedUp: Boolean = false) - : RealmObject() { + var backedUp: Boolean = false) : + RealmObject() { fun getInboundGroupSession(): OlmInboundGroupSessionWrapper2? { return try { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt index 8f41057807..0b69311c57 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OlmSessionEntity.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.crypto.store.db.model -import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm -import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm import org.matrix.olm.OlmSession internal fun OlmSessionEntity.Companion.createPrimaryKey(sessionId: String, deviceKey: String) = "$sessionId|$deviceKey" @@ -29,8 +29,8 @@ internal open class OlmSessionEntity(@PrimaryKey var primaryKey: String = "", var sessionId: String? = null, var deviceKey: String? = null, var olmSessionData: String? = null, - var lastReceivedMessageTs: Long = 0) - : RealmObject() { + var lastReceivedMessageTs: Long = 0) : + RealmObject() { fun getOlmSession(): OlmSession? { return deserializeFromRealm(olmSessionData) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt index 442dda1d71..a19547fddc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt @@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Types +import io.realm.RealmObject +import io.realm.annotations.Index import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.internal.crypto.GossipRequestType import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequest @@ -26,8 +28,6 @@ import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.OutgoingSecretRequest import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.di.MoshiProvider -import io.realm.RealmObject -import io.realm.annotations.Index internal open class OutgoingGossipingRequestEntity( @Index var requestId: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt index 2864ab768d..6d7889053b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.crypto.store.db.model -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode import io.realm.RealmObject import io.realm.annotations.Index +import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode /** * When an encrypted message is sent in a room, the megolm key might not be sent to all devices present in the room. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt index eea2f6f31b..05eed9256e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CrossSigningInfoEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields internal fun CrossSigningInfoEntity.Companion.getOrCreate(realm: Realm, userId: String): CrossSigningInfoEntity { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CryptoRoomEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CryptoRoomEntityQueries.kt index 5ebf8b1ed5..5750cc1f67 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CryptoRoomEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/CryptoRoomEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields /** * Get or create a room diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt index 1d5ca2d3cc..c9523d63ce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/DeviceInfoEntityQueries.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey /** * Get or create a device info 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 39117512bb..2784e58425 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 @@ -29,8 +29,7 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, sessionId: String, userId: String, deviceId: String, - deviceIdentityKey: String?) - : SharedSessionEntity? { + deviceIdentityKey: String?): SharedSessionEntity? { return realm.where() .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) .equalTo(SharedSessionEntityFields.SESSION_ID, sessionId) @@ -41,8 +40,7 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, .findFirst() } -internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String) - : RealmResults { +internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String): RealmResults { return realm.where() .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) .equalTo(SharedSessionEntityFields.SESSION_ID, sessionId) @@ -55,8 +53,7 @@ internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, userId: String, deviceId: String, deviceIdentityKey: String, - chainIndex: Int) - : SharedSessionEntity { + chainIndex: Int): SharedSessionEntity { return realm.createObject().apply { this.roomId = roomId this.algorithm = MXCRYPTO_ALGORITHM_MEGOLM diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt index 3c6c594a70..b8a3e36137 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields internal fun WithHeldSessionEntity.Companion.get(realm: Realm, roomId: String, sessionId: String): WithHeldSessionEntity? { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt index bdb8e8d137..ca04bac5d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceTask.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams -import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task @@ -46,8 +46,8 @@ internal class DefaultDeleteDeviceTask @Inject constructor( cryptoApi.deleteDevice(params.deviceId, DeleteDeviceParams(params.userAuthParam?.asMap())) } } catch (throwable: Throwable) { - if (params.userInteractiveAuthInterceptor == null - || !handleUIA( + if (params.userInteractiveAuthInterceptor == null || + !handleUIA( failure = throwable, interceptor = params.userInteractiveAuthInterceptor, retryBlock = { authUpdate -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt index 1d40e5defd..e2fd54f0d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt @@ -125,8 +125,8 @@ internal class DefaultInitializeCrossSigningTask @Inject constructor( try { uploadSigningKeysTask.execute(uploadSigningKeysParams) } catch (failure: Throwable) { - if (params.interactiveAuthInterceptor == null - || !handleUIA( + if (params.interactiveAuthInterceptor == null || + !handleUIA( failure = failure, interceptor = params.interactiveAuthInterceptor, retryBlock = { authUpdate -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt index 08c767ba34..6cb14ded63 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.internal.crypto.model.rest.UploadSigningKeysBody import org.matrix.android.sdk.internal.crypto.model.toRest import org.matrix.android.sdk.internal.network.GlobalErrorReceiver diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt index fde9f70e7b..68f1cf62d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt @@ -114,8 +114,8 @@ internal class DefaultIncomingSASDefaultVerificationTransaction( // No common key sharing/hashing/hmac/SAS methods. // If a device is unable to complete the verification because the devices are unable to find a common key sharing, // hashing, hmac, or SAS method, then it should send a m.key.verification.cancel message - if (listOf(agreedProtocol, agreedHash, agreedMac).any { it.isNullOrBlank() } - || agreedShortCode.isNullOrEmpty()) { + if (listOf(agreedProtocol, agreedHash, agreedMac).any { it.isNullOrBlank() } || + agreedShortCode.isNullOrEmpty()) { // Failed to find agreement Timber.e("## SAS Failed to find agreement ") cancel(CancelCode.UnknownMethod) @@ -241,12 +241,12 @@ internal class DefaultIncomingSASDefaultVerificationTransaction( override fun onKeyVerificationMac(vMac: ValidVerificationInfoMac) { Timber.v("## SAS I: received mac for request id:$transactionId") // Check for state? - if (state != VerificationTxState.SendingKey - && state != VerificationTxState.KeySent - && state != VerificationTxState.ShortCodeReady - && state != VerificationTxState.ShortCodeAccepted - && state != VerificationTxState.SendingMac - && state != VerificationTxState.MacSent) { + if (state != VerificationTxState.SendingKey && + state != VerificationTxState.KeySent && + state != VerificationTxState.ShortCodeReady && + state != VerificationTxState.ShortCodeAccepted && + state != VerificationTxState.SendingMac && + state != VerificationTxState.MacSent) { Timber.e("## SAS I: received key from invalid state $state") cancel(CancelCode.UnexpectedMessage) return diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt index 1a41f89006..e203f03b06 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt @@ -144,10 +144,10 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction( return } // Check that the agreement is correct - if (!KNOWN_AGREEMENT_PROTOCOLS.contains(accept.keyAgreementProtocol) - || !KNOWN_HASHES.contains(accept.hash) - || !KNOWN_MACS.contains(accept.messageAuthenticationCode) - || accept.shortAuthenticationStrings.intersect(KNOWN_SHORT_CODES).isEmpty()) { + if (!KNOWN_AGREEMENT_PROTOCOLS.contains(accept.keyAgreementProtocol) || + !KNOWN_HASHES.contains(accept.hash) || + !KNOWN_MACS.contains(accept.messageAuthenticationCode) || + accept.shortAuthenticationStrings.intersect(KNOWN_SHORT_CODES).isEmpty()) { Timber.e("## SAS O: received invalid accept") cancel(CancelCode.UnknownMethod) return @@ -233,12 +233,12 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction( override fun onKeyVerificationMac(vMac: ValidVerificationInfoMac) { Timber.v("## SAS O: onKeyVerificationMac id:$transactionId") // There is starting to be a huge amount of state / race here :/ - if (state != VerificationTxState.OnKeyReceived - && state != VerificationTxState.ShortCodeReady - && state != VerificationTxState.ShortCodeAccepted - && state != VerificationTxState.KeySent - && state != VerificationTxState.SendingMac - && state != VerificationTxState.MacSent) { + if (state != VerificationTxState.OnKeyReceived && + state != VerificationTxState.ShortCodeReady && + state != VerificationTxState.ShortCodeAccepted && + state != VerificationTxState.KeySent && + state != VerificationTxState.SendingMac && + state != VerificationTxState.MacSent) { Timber.e("## SAS O: received mac from invalid state $state") cancel(CancelCode.UnexpectedMessage) return diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt index d9da88770c..768109979d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt @@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.crypto.verification import android.os.Handler import android.os.Looper import dagger.Lazy +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME @@ -82,8 +84,6 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -537,8 +537,8 @@ internal class DefaultVerificationService @Inject constructor( // as we are the one requesting in first place (or we accepted the request) // I need to check if the pending request was related to this device also val autoAccept = getExistingVerificationRequests(otherUserId).any { - it.transactionId == startReq.transactionId - && (it.requestInfo?.fromDevice == this.deviceId || it.readyInfo?.fromDevice == this.deviceId) + it.transactionId == startReq.transactionId && + (it.requestInfo?.fromDevice == this.deviceId || it.readyInfo?.fromDevice == this.deviceId) } val tx = DefaultIncomingSASDefaultVerificationTransaction( // this, @@ -1126,8 +1126,10 @@ internal class DefaultVerificationService @Inject constructor( } } - override fun requestKeyVerificationInDMs(methods: List, otherUserId: String, roomId: String, localId: String?) - : PendingVerificationRequest { + override fun requestKeyVerificationInDMs(methods: List, + otherUserId: String, + roomId: String, + localId: String?): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") val requestsForUser = pendingRequests.getOrPut(otherUserId) { mutableListOf() } @@ -1278,8 +1280,8 @@ internal class DefaultVerificationService @Inject constructor( private fun updatePendingRequest(updated: PendingVerificationRequest) { val requestsForUser = pendingRequests.getOrPut(updated.otherUserId) { mutableListOf() } val index = requestsForUser.indexOfFirst { - it.transactionId == updated.transactionId - || it.transactionId == null && it.localId == updated.localId + it.transactionId == updated.transactionId || + it.transactionId == null && it.localId == updated.localId } if (index != -1) { requestsForUser.removeAt(index) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt index 538d7b56e9..481ce85f70 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt @@ -34,8 +34,8 @@ import javax.inject.Inject * Possible next worker : None */ internal class SendVerificationMessageWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt index 21a6ba41b1..f727aff39d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt @@ -73,8 +73,8 @@ internal interface VerificationInfoStart : VerificationInfo) - : VerificationInfoAccept = MessageVerificationAcceptContent.create( + shortAuthenticationStrings: List): VerificationInfoAccept = + MessageVerificationAcceptContent.create( tid, keyAgreementProtocol, hash, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt index ee58880eb8..7341d4656a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/DatabaseCleaner.kt @@ -21,6 +21,7 @@ import io.realm.RealmConfiguration import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.database.helper.nextDisplayIndex import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.ChunkEntityFields @@ -30,7 +31,6 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields import org.matrix.android.sdk.internal.database.model.deleteOnCascade import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.task.TaskExecutor import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt index 758c7aa5b9..115025cc7d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt @@ -31,8 +31,8 @@ import timber.log.Timber import javax.inject.Inject internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration, - private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>) - : RealmLiveEntityObserver(realmConfiguration) { + private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>) : + RealmLiveEntityObserver(realmConfiguration) { override val query = Monarchy.Query { it.where(EventInsertEntity::class.java).equalTo(EventInsertEntityFields.CAN_BE_PROCESSED, true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt index d5ff7a0f84..7c622146d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt @@ -19,9 +19,9 @@ import android.content.Context import android.util.Base64 import androidx.core.content.edit import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.internal.session.securestorage.SecretStoringUtils -import io.realm.RealmConfiguration import timber.log.Timber import java.security.SecureRandom import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt index c602ed7075..50eb086f9a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmLiveEntityObserver.kt @@ -17,8 +17,6 @@ package org.matrix.android.sdk.internal.database import com.zhuinden.monarchy.Monarchy -import org.matrix.android.sdk.api.session.SessionLifecycleObserver -import org.matrix.android.sdk.internal.util.createBackgroundHandler import io.realm.Realm import io.realm.RealmChangeListener import io.realm.RealmConfiguration @@ -29,13 +27,15 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.cancelChildren import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.SessionLifecycleObserver +import org.matrix.android.sdk.internal.util.createBackgroundHandler import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference internal interface LiveEntityObserver : SessionLifecycleObserver -internal abstract class RealmLiveEntityObserver(protected val realmConfiguration: RealmConfiguration) - : LiveEntityObserver, RealmChangeListener> { +internal abstract class RealmLiveEntityObserver(protected val realmConfiguration: RealmConfiguration) : + LiveEntityObserver, RealmChangeListener> { private companion object { val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt index 52fbabb49f..8c62c345d0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionProvider.kt @@ -21,8 +21,8 @@ import androidx.annotation.MainThread import com.zhuinden.monarchy.Monarchy import io.realm.Realm import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.api.session.SessionLifecycleObserver +import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.SessionScope import javax.inject.Inject import kotlin.concurrent.getOrSet @@ -32,8 +32,8 @@ import kotlin.concurrent.getOrSet * instance. This does check each time if you are on the main thread or not and returns the appropriate realm instance. */ @SessionScope -internal class RealmSessionProvider @Inject constructor(@SessionDatabase private val monarchy: Monarchy) - : SessionLifecycleObserver { +internal class RealmSessionProvider @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : + SessionLifecycleObserver { private val realmThreadLocal = ThreadLocal() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt index e262b40419..f74e4b0f4c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt @@ -16,6 +16,9 @@ package org.matrix.android.sdk.internal.database.helper +import io.realm.Realm +import io.realm.Sort +import io.realm.kotlin.createObject import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields @@ -33,9 +36,6 @@ import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.extensions.assertIsManaged import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection -import io.realm.Realm -import io.realm.Sort -import io.realm.kotlin.createObject import timber.log.Timber internal fun ChunkEntity.merge(roomId: String, chunkToMerge: ChunkEntity, direction: PaginationDirection) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt index 90e867749e..3993e8e799 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/TimelineEventEntityHelper.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.database.helper +import io.realm.Realm import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields -import io.realm.Realm internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long { val currentIdNum = realm.where(TimelineEventEntity::class.java).max(TimelineEventEntityFields.LOCAL_ID) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/IsUselessResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/IsUselessResolver.kt index 5d7afc50d6..d704ecac8e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/IsUselessResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/IsUselessResolver.kt @@ -29,8 +29,8 @@ internal object IsUselessResolver { return when (event.type) { EventType.STATE_ROOM_MEMBER -> { // Call toContent(), to filter out null value - event.content != null - && event.content.toContent() == event.resolvedPrevContent()?.toContent() + event.content != null && + event.content.toContent() == event.resolvedPrevContent()?.toContent() } else -> false } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PollResponseAggregatedSummaryEntityMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PollResponseAggregatedSummaryEntityMapper.kt index b26e7e88e3..00998af9bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PollResponseAggregatedSummaryEntityMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PollResponseAggregatedSummaryEntityMapper.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.mapper +import io.realm.RealmList import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity -import io.realm.RealmList internal object PollResponseAggregatedSummaryEntityMapper { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt index 4dc8712afb..bcd30cb54b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.database.model +import io.realm.RealmObject +import io.realm.annotations.Index import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.di.MoshiProvider -import io.realm.RealmObject -import io.realm.annotations.Index import org.matrix.android.sdk.internal.extensions.assertIsManaged internal open class EventEntity(@Index var eventId: String = "", diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt index 25a041e3d0..527f782359 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupEntity.kt @@ -16,16 +16,16 @@ package org.matrix.android.sdk.internal.database.model -import org.matrix.android.sdk.api.session.room.model.Membership import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.api.session.room.model.Membership /** * This class is used to store group info (groupId and membership) from the sync response. * Then GetGroupDataTask is called regularly to fetch group information from the homeserver. */ -internal open class GroupEntity(@PrimaryKey var groupId: String = "") - : RealmObject() { +internal open class GroupEntity(@PrimaryKey var groupId: String = "") : + RealmObject() { private var membershipStr: String = Membership.NONE.name var membership: Membership diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt index 8982436ccc..4ba45dcda2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/GroupSummaryEntity.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.database.model -import org.matrix.android.sdk.api.session.room.model.Membership import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.api.session.room.model.Membership internal open class GroupSummaryEntity(@PrimaryKey var groupId: String = "", var displayName: String = "", diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt index 571bc71c27..4125d90891 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt @@ -15,9 +15,9 @@ */ package org.matrix.android.sdk.internal.database.model -import org.matrix.android.sdk.api.pushrules.RuleKind import io.realm.RealmList import io.realm.RealmObject +import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.internal.extensions.clearWith internal open class PushRulesEntity( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt index 65483e05bf..2997d5d7d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomEntity.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.database.model -import org.matrix.android.sdk.api.session.room.model.Membership import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.api.session.room.model.Membership internal open class RoomEntity(@PrimaryKey var roomId: String = "", var chunks: RealmList = RealmList(), diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMemberSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMemberSummaryEntity.kt index e970fab397..75771ff12c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMemberSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomMemberSummaryEntity.kt @@ -16,10 +16,11 @@ package org.matrix.android.sdk.internal.database.model -import org.matrix.android.sdk.api.session.room.model.Membership import io.realm.RealmObject import io.realm.annotations.Index import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.util.MatrixItem internal open class RoomMemberSummaryEntity(@PrimaryKey var primaryKey: String = "", @Index var userId: String = "", @@ -39,7 +40,7 @@ internal open class RoomMemberSummaryEntity(@PrimaryKey var primaryKey: String = membershipStr = value.name } - fun getBestName() = displayName?.takeIf { it.isNotBlank() } ?: userId + fun toMatrixItem() = MatrixItem.UserItem(userId, displayName, avatarUrl) companion object } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/BreadcrumbsEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/BreadcrumbsEntityQuery.kt index 0463d52fff..3b24ff5f9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/BreadcrumbsEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/BreadcrumbsEntityQuery.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.BreadcrumbsEntity import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.BreadcrumbsEntity internal fun BreadcrumbsEntity.Companion.get(realm: Realm): BreadcrumbsEntity? { return realm.where().findFirst() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt index f7d2823303..156a8dd767 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ChunkEntity -import org.matrix.android.sdk.internal.database.model.ChunkEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.RealmResults import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ChunkEntity +import org.matrix.android.sdk.internal.database.model.ChunkEntityFields internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/CurrentStateEventEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/CurrentStateEventEntityQueries.kt index 9a3622e2dc..716783f2ba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/CurrentStateEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/CurrentStateEventEntityQueries.kt @@ -17,33 +17,46 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity -import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.createObject +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields -internal fun CurrentStateEventEntity.Companion.whereType(realm: Realm, roomId: String, type: String): RealmQuery { +internal fun CurrentStateEventEntity.Companion.whereType(realm: Realm, + roomId: String, + type: String): RealmQuery { return realm.where(CurrentStateEventEntity::class.java) .equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId) .equalTo(CurrentStateEventEntityFields.TYPE, type) } -internal fun CurrentStateEventEntity.Companion.whereStateKey(realm: Realm, roomId: String, type: String, stateKey: String) - : RealmQuery { +internal fun CurrentStateEventEntity.Companion.whereStateKey(realm: Realm, + roomId: String, + type: String, + stateKey: String): RealmQuery { return whereType(realm = realm, roomId = roomId, type = type) .equalTo(CurrentStateEventEntityFields.STATE_KEY, stateKey) } -internal fun CurrentStateEventEntity.Companion.getOrNull(realm: Realm, roomId: String, stateKey: String, type: String): CurrentStateEventEntity? { +internal fun CurrentStateEventEntity.Companion.getOrNull(realm: Realm, + roomId: String, + stateKey: String, + type: String): CurrentStateEventEntity? { return whereStateKey(realm = realm, roomId = roomId, type = type, stateKey = stateKey).findFirst() } -internal fun CurrentStateEventEntity.Companion.getOrCreate(realm: Realm, roomId: String, stateKey: String, type: String): CurrentStateEventEntity { +internal fun CurrentStateEventEntity.Companion.getOrCreate(realm: Realm, + roomId: String, + stateKey: String, + type: String): CurrentStateEventEntity { return getOrNull(realm = realm, roomId = roomId, stateKey = stateKey, type = type) ?: create(realm, roomId, stateKey, type) } -private fun create(realm: Realm, roomId: String, stateKey: String, type: String): CurrentStateEventEntity { +private fun create(realm: Realm, + roomId: String, + stateKey: String, + type: String): CurrentStateEventEntity { return realm.createObject().apply { this.type = type this.roomId = roomId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt index c3cae3d268..14cb7e22da 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity -import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity +import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.TimelineEventEntity internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, roomId: String, eventId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt index 57e24cf88f..240b2a0691 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventEntityQueries.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.EventEntity -import org.matrix.android.sdk.internal.database.model.EventEntityFields -import org.matrix.android.sdk.internal.database.model.EventInsertEntity -import org.matrix.android.sdk.internal.database.model.EventInsertType import io.realm.Realm import io.realm.RealmList import io.realm.RealmQuery import io.realm.kotlin.where import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.internal.database.model.EventEntity +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.EventInsertEntity +import org.matrix.android.sdk.internal.database.model.EventInsertType internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInsertType): EventEntity { val eventEntity = realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/FilterEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/FilterEntityQueries.kt index c76e606805..3968169e08 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/FilterEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/FilterEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.FilterEntity -import org.matrix.android.sdk.internal.session.filter.FilterFactory import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.FilterEntity +import org.matrix.android.sdk.internal.session.filter.FilterFactory /** * Get the current filter diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt index 9a1f2b3782..020592d1dd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupEntityQueries.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.database.query +import io.realm.Realm +import io.realm.RealmQuery +import io.realm.kotlin.where import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.internal.database.model.GroupEntity import org.matrix.android.sdk.internal.database.model.GroupEntityFields import org.matrix.android.sdk.internal.query.process -import io.realm.Realm -import io.realm.RealmQuery -import io.realm.kotlin.where internal fun GroupEntity.Companion.where(realm: Realm, groupId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt index fbfd8bd19e..8131598d95 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/GroupSummaryEntityQueries.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity -import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity +import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields internal fun GroupSummaryEntity.Companion.where(realm: Realm, groupId: String? = null): RealmQuery { val query = realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/HomeServerCapabilitiesQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/HomeServerCapabilitiesQueries.kt index b0b4f5a83d..4f8ac20e94 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/HomeServerCapabilitiesQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/HomeServerCapabilitiesQueries.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity /** * Get the current HomeServerCapabilitiesEntity, return null if it does not exist diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt index 359b256844..1f6b210252 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/PushersQueries.kt @@ -15,6 +15,9 @@ */ package org.matrix.android.sdk.internal.database.query +import io.realm.Realm +import io.realm.RealmQuery +import io.realm.kotlin.where import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.internal.database.model.PushRuleEntity import org.matrix.android.sdk.internal.database.model.PushRuleEntityFields @@ -22,9 +25,6 @@ import org.matrix.android.sdk.internal.database.model.PushRulesEntity import org.matrix.android.sdk.internal.database.model.PushRulesEntityFields import org.matrix.android.sdk.internal.database.model.PusherEntity import org.matrix.android.sdk.internal.database.model.PusherEntityFields -import io.realm.Realm -import io.realm.RealmQuery -import io.realm.kotlin.where internal fun PusherEntity.Companion.where(realm: Realm, pushKey: String? = null): RealmQuery { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadMarkerEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadMarkerEntityQueries.kt index 35fb2b068b..d80fe86aae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadMarkerEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadMarkerEntityQueries.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity -import org.matrix.android.sdk.internal.database.model.ReadMarkerEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity +import org.matrix.android.sdk.internal.database.model.ReadMarkerEntityFields internal fun ReadMarkerEntity.Companion.where(realm: Realm, roomId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt index 5423025823..60096777d9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadQueries.kt @@ -15,13 +15,13 @@ */ package org.matrix.android.sdk.internal.database.query +import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity import org.matrix.android.sdk.internal.database.model.TimelineEventEntity -import io.realm.Realm -import io.realm.RealmConfiguration internal fun isEventRead(realmConfiguration: RealmConfiguration, userId: String?, @@ -39,19 +39,18 @@ internal fun isEventRead(realmConfiguration: RealmConfiguration, val liveChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId) ?: return@use val eventToCheck = liveChunk.timelineEvents.find(eventId) isEventRead = when { - eventToCheck == null -> { - // This can happen in case of fast lane Event - false - } + eventToCheck == null -> hasReadMissingEvent( + realm = realm, + latestChunkEntity = liveChunk, + roomId = roomId, + userId = userId, + eventId = eventId + ) eventToCheck.root?.sender == userId -> true else -> { - val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst() - ?: return@use - val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex - ?: Int.MIN_VALUE - val eventToCheckIndex = eventToCheck.displayIndex - - eventToCheckIndex <= readReceiptIndex + val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst() ?: return@use + val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.displayIndex ?: Int.MIN_VALUE + eventToCheck.displayIndex <= readReceiptIndex } } } @@ -59,6 +58,24 @@ internal fun isEventRead(realmConfiguration: RealmConfiguration, return isEventRead } +/** + * Missing events can be caused by the latest timeline chunk no longer contain an older event or + * by fast lane eagerly displaying events before the database has finished updating + */ +private fun hasReadMissingEvent(realm: Realm, latestChunkEntity: ChunkEntity, roomId: String, userId: String, eventId: String): Boolean { + return realm.doesEventExistInChunkHistory(eventId) && realm.hasReadReceiptInLatestChunk(latestChunkEntity, roomId, userId) +} + +private fun Realm.doesEventExistInChunkHistory(eventId: String): Boolean { + return ChunkEntity.findIncludingEvent(this, eventId) != null +} + +private fun Realm.hasReadReceiptInLatestChunk(latestChunkEntity: ChunkEntity, roomId: String, userId: String): Boolean { + return ReadReceiptEntity.where(this, roomId = roomId, userId = userId).findFirst()?.let { + latestChunkEntity.timelineEvents.find(it.eventId) + } != null +} + internal fun isReadMarkerMoreRecent(realmConfiguration: RealmConfiguration, roomId: String?, eventId: String?): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptEntityQueries.kt index 1a5e8fcf89..b180c06e2c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptEntityQueries.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity -import org.matrix.android.sdk.internal.database.model.ReadReceiptEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity +import org.matrix.android.sdk.internal.database.model.ReadReceiptEntityFields internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String, userId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptsSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptsSummaryEntityQueries.kt index 97f8418403..a35df57b7b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptsSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReadReceiptsSummaryEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity -import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity +import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntityFields internal fun ReadReceiptsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReferencesAggregatedSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReferencesAggregatedSummaryEntityQueries.kt index 8b3929cd60..14beb2d853 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReferencesAggregatedSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ReferencesAggregatedSummaryEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntity -import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntity +import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntityFields internal fun ReferencesAggregatedSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery { val query = realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt index a551f97379..08bb9e7ff3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomEntityQueries.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.database.query +import io.realm.Realm +import io.realm.RealmQuery +import io.realm.kotlin.where import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.RoomEntity import org.matrix.android.sdk.internal.database.model.RoomEntityFields -import io.realm.Realm -import io.realm.RealmQuery -import io.realm.kotlin.where internal fun RoomEntity.Companion.where(realm: Realm, roomId: String): RealmQuery { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomMemberEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomMemberEntityQueries.kt index 0747b12665..a19a9cf725 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomMemberEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomMemberEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity -import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields internal fun RoomMemberSummaryEntity.Companion.where(realm: Realm, roomId: String, userId: String? = null): RealmQuery { val query = realm diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt index 2af5dcf0ae..5294f849af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.RealmResults import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields internal fun RoomSummaryEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery { val query = realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ScalarTokenQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ScalarTokenQuery.kt index 53fd525092..a7d85d676c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ScalarTokenQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ScalarTokenQuery.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.ScalarTokenEntity -import org.matrix.android.sdk.internal.database.model.ScalarTokenEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.ScalarTokenEntity +import org.matrix.android.sdk.internal.database.model.ScalarTokenEntityFields internal fun ScalarTokenEntity.Companion.where(realm: Realm, serverUrl: String): RealmQuery { return realm diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/TimelineEventEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/TimelineEventEntityQueries.kt index 148232cf94..aa1ce41bb7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/TimelineEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/TimelineEventEntityQueries.kt @@ -119,8 +119,7 @@ internal fun RealmList.find(eventId: String): TimelineEvent internal fun TimelineEventEntity.Companion.findAllInRoomWithSendStates(realm: Realm, roomId: String, - sendStates: List) - : RealmResults { + sendStates: List): RealmResults { return whereRoomId(realm, roomId) .filterSendStates(sendStates) .findAll() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt index 4af4da0a22..aa9d409a2a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserDraftsEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.UserDraftsEntity -import org.matrix.android.sdk.internal.database.model.UserDraftsEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.UserDraftsEntity +import org.matrix.android.sdk.internal.database.model.UserDraftsEntityFields internal fun UserDraftsEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery { val query = realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserEntityQueries.kt index 6a5528e3db..3159f89311 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/UserEntityQueries.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.database.query -import org.matrix.android.sdk.internal.database.model.UserEntity -import org.matrix.android.sdk.internal.database.model.UserEntityFields import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where +import org.matrix.android.sdk.internal.database.model.UserEntity +import org.matrix.android.sdk.internal.database.model.UserEntityFields internal fun UserEntity.Companion.where(realm: Realm, userId: String): RealmQuery { return realm diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt index b58fb3e683..4cd960f426 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixModule.kt @@ -20,11 +20,11 @@ import android.content.Context import android.content.res.Resources import dagger.Module import dagger.Provides -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import org.matrix.android.sdk.internal.util.createBackgroundHandler import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.android.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher +import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +import org.matrix.android.sdk.internal.util.createBackgroundHandler import org.matrix.olm.OlmManager import java.io.File import java.util.concurrent.Executors diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt index 0d0892b608..fa59b94c17 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt @@ -20,15 +20,15 @@ import com.facebook.stetho.okhttp3.StethoInterceptor import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.internal.network.ApiInterceptor import org.matrix.android.sdk.internal.network.TimeOutInterceptor import org.matrix.android.sdk.internal.network.UserAgentInterceptor import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import org.matrix.android.sdk.internal.network.ApiInterceptor import java.util.concurrent.TimeUnit @Module diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt index ad2aff4c9d..445b6be8e8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt @@ -17,6 +17,9 @@ package org.matrix.android.sdk.internal.legacy import android.content.Context +import io.realm.Realm +import io.realm.RealmConfiguration +import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.DiscoveryInformation import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig @@ -30,9 +33,6 @@ import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.legacy.riot.LoginStorage import org.matrix.android.sdk.internal.network.ssl.Fingerprint import org.matrix.android.sdk.internal.util.md5 -import io.realm.Realm -import io.realm.RealmConfiguration -import kotlinx.coroutines.runBlocking import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt index 56d372faa5..17fd0925f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt @@ -75,9 +75,9 @@ class WellKnown { (config as? Map<*, *>)?.let { map -> val apiUrl = map["api_url"] as? String val uiUrl = map["ui_url"] as? String ?: apiUrl - if (apiUrl != null - && apiUrl.startsWith("https://") - && uiUrl!!.startsWith("https://")) { + if (apiUrl != null && + apiUrl.startsWith("https://") && + uiUrl!!.startsWith("https://")) { managers.add(WellKnownManagerConfig( apiUrl = apiUrl, uiUrl = uiUrl diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/AccessTokenInterceptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/AccessTokenInterceptor.kt index b11fb6a5ee..a34606a6bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/AccessTokenInterceptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/AccessTokenInterceptor.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.network -import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import okhttp3.Interceptor import okhttp3.Response +import org.matrix.android.sdk.internal.network.token.AccessTokenProvider internal class AccessTokenInterceptor(private val accessTokenProvider: AccessTokenProvider) : Interceptor { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt index c149ed2591..e32f6be6fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.network import androidx.annotation.WorkerThread +import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.homeserver.HomeServerPinger import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver -import kotlinx.coroutines.runBlocking import java.util.Collections import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject @@ -43,8 +43,8 @@ interface NetworkConnectivityChecker { @SessionScope internal class DefaultNetworkConnectivityChecker @Inject constructor(private val homeServerPinger: HomeServerPinger, private val backgroundDetectionObserver: BackgroundDetectionObserver, - private val networkCallbackStrategy: NetworkCallbackStrategy) - : NetworkConnectivityChecker { + private val networkCallbackStrategy: NetworkCallbackStrategy) : + NetworkConnectivityChecker { private val hasInternetAccess = AtomicBoolean(true) private val listeners = Collections.synchronizedSet(LinkedHashSet()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt index e045cebd3e..927d9f7dd2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt @@ -74,10 +74,10 @@ internal suspend inline fun executeRequest(globalErrorReceiver: GlobalErr currentRetryCount++ - if (exception is Failure.ServerError - && exception.httpCode == 429 - && exception.error.code == MatrixError.M_LIMIT_EXCEEDED - && currentRetryCount < maxRetriesCount) { + if (exception is Failure.ServerError && + exception.httpCode == 429 && + exception.error.code == MatrixError.M_LIMIT_EXCEEDED && + currentRetryCount < maxRetriesCount) { // 429, we can retry delay(exception.getRetryDelay(1_000)) } else if (canRetry && currentRetryCount < maxRetriesCount && exception.shouldBeRetried()) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt index 8a03102527..60055be9ec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitExtensions.kt @@ -91,8 +91,8 @@ private fun toFailure(errorBody: ResponseBody?, httpCode: Int, globalErrorReceiv matrixError.code == MatrixError.M_CONSENT_NOT_GIVEN && !matrixError.consentUri.isNullOrBlank() -> { globalErrorReceiver?.handleGlobalError(GlobalError.ConsentNotGivenError(matrixError.consentUri)) } - httpCode == HttpURLConnection.HTTP_UNAUTHORIZED /* 401 */ - && matrixError.code == MatrixError.M_UNKNOWN_TOKEN -> { + httpCode == HttpURLConnection.HTTP_UNAUTHORIZED && /* 401 */ + matrixError.code == MatrixError.M_UNKNOWN_TOKEN -> { globalErrorReceiver?.handleGlobalError(GlobalError.InvalidToken(matrixError.isSoftLogout.orFalse())) } matrixError.code == MatrixError.ORG_MATRIX_EXPIRED_ACCOUNT -> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt index 57eab6a8dd..00e15c283e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt @@ -73,8 +73,8 @@ internal class UserAgentHolder @Inject constructor(private val context: Context, // if there is no user agent or cannot parse it if (null == systemUserAgent || systemUserAgent.lastIndexOf(")") == -1 || !systemUserAgent.contains("(")) { - userAgent = (appName + "/" + appVersion + " ( Flavour " + flavorDescription - + "; MatrixAndroidSdk2 " + BuildConfig.SDK_VERSION + ")") + userAgent = (appName + "/" + appVersion + " ( Flavour " + flavorDescription + + "; MatrixAndroidSdk2 " + BuildConfig.SDK_VERSION + ")") } else { // update userAgent = appName + "/" + appVersion + " " + diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt index b4a2d191e2..3920c3b527 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.network.httpclient +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.internal.network.AccessTokenInterceptor import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.ssl.CertUtil import org.matrix.android.sdk.internal.network.token.AccessTokenProvider -import okhttp3.OkHttpClient import timber.log.Timber internal fun OkHttpClient.Builder.addAccessTokenInterceptor(accessTokenProvider: AccessTokenProvider): OkHttpClient.Builder { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt index 14d275e021..27684bbf1a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt @@ -20,7 +20,6 @@ import androidx.annotation.Nullable import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter - import com.squareup.moshi.Moshi import java.io.IOException import java.lang.reflect.Type diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt index 976751446b..92c7f3f236 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.network.ssl -import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import okhttp3.ConnectionSpec import okhttp3.internal.tls.OkHostnameVerifier +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import timber.log.Timber import java.security.KeyStore import java.security.MessageDigest diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt index b1001bd39c..6f245aa6d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.network.ssl import java.security.cert.CertificateException import java.security.cert.X509Certificate - import javax.net.ssl.X509TrustManager /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index 22167bc77a..d41bf8a702 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -223,6 +223,8 @@ internal class DefaultSession @Inject constructor( override fun getSyncStateLive() = getSyncThread().liveState() + override fun syncFlow() = getSyncThread().syncFlow() + override fun getSyncState() = getSyncThread().currentState() override fun hasAlreadySynced(): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt index 7a687b774b..a650fa2d64 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/EventInsertLiveProcessor.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session +import io.realm.Realm import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.internal.database.model.EventInsertType -import io.realm.Realm internal interface EventInsertLiveProcessor { 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 2003a66c94..71031a4614 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,7 +46,6 @@ 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.relation.SendRelationWorker 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 @@ -115,8 +114,6 @@ internal interface SessionComponent { fun inject(worker: SendEventWorker) - fun inject(worker: SendRelationWorker) - fun inject(worker: MultipleEventSendingDispatcherWorker) fun inject(worker: RedactEventWorker) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionCoroutineScopeHolder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionCoroutineScopeHolder.kt index 82a8f79fd5..2a741ddb9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionCoroutineScopeHolder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionCoroutineScopeHolder.kt @@ -20,12 +20,12 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren -import javax.inject.Inject import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.SessionLifecycleObserver +import javax.inject.Inject @SessionScope -internal class SessionCoroutineScopeHolder @Inject constructor(): SessionLifecycleObserver { +internal class SessionCoroutineScopeHolder @Inject constructor() : SessionLifecycleObserver { val scope: CoroutineScope = CoroutineScope(SupervisorJob()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt index 02c3735998..7b21ba2e63 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/ChangePasswordTask.kt @@ -45,9 +45,9 @@ internal class DefaultChangePasswordTask @Inject constructor( } catch (throwable: Throwable) { val registrationFlowResponse = throwable.toRegistrationFlowResponse() - if (registrationFlowResponse != null + if (registrationFlowResponse != null && /* Avoid infinite loop */ - && changePasswordParams.auth?.session == null) { + changePasswordParams.auth?.session == null) { // Retry with authentication executeRequest(globalErrorReceiver) { accountAPI.changePassword( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/CacheModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/CacheModule.kt index 83c7d2b0b5..60adb21242 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/CacheModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/CacheModule.kt @@ -19,9 +19,9 @@ package org.matrix.android.sdk.internal.session.cache import dagger.Binds import dagger.Module import dagger.Provides +import io.realm.RealmConfiguration import org.matrix.android.sdk.api.session.cache.CacheService import org.matrix.android.sdk.internal.di.SessionDatabase -import io.realm.RealmConfiguration @Module internal abstract class CacheModule { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/ClearCacheTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/ClearCacheTask.kt index 894c3a4723..7f6b545c97 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/ClearCacheTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cache/ClearCacheTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.cache +import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.task.Task -import io.realm.RealmConfiguration import javax.inject.Inject internal interface ClearCacheTask : Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt index bdc254fc99..3f199c5cce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/CallEventProcessor.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session.call import io.realm.Realm +import org.matrix.android.sdk.api.logger.LoggerTag 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.internal.database.model.EventInsertType -import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber @@ -29,8 +29,8 @@ import javax.inject.Inject private val loggerTag = LoggerTag("CallEventProcessor", LoggerTag.VOIP) @SessionScope -internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler) - : EventInsertLiveProcessor { +internal class CallEventProcessor @Inject constructor(private val callSignalingHandler: CallSignalingHandler) : + EventInsertLiveProcessor { private val allowedTypes = listOf( EventType.CALL_ANSWER, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt index 8870d92a35..d4374e0702 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt @@ -16,22 +16,22 @@ package org.matrix.android.sdk.internal.session.cleanup +import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.crypto.CryptoModule import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.CryptoDatabase -import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UserMd5 import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.SessionModule import org.matrix.android.sdk.internal.session.cache.ClearCacheTask -import io.realm.Realm -import io.realm.RealmConfiguration import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt index e4efdaa254..5c8cf99dc6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt @@ -16,14 +16,14 @@ package org.matrix.android.sdk.internal.session.content +import org.matrix.android.sdk.api.MatrixUrls +import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.util.ensureTrailingSlash import javax.inject.Inject -private const val MATRIX_CONTENT_URI_SCHEME = "mxc://" - internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectionConfig: HomeServerConnectionConfig) : ContentUrlResolver { private val baseUrl = homeServerConnectionConfig.homeServerUriBase.toString().ensureTrailingSlash() @@ -33,7 +33,7 @@ internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectio override fun resolveFullSize(contentUrl: String?): String? { return contentUrl // do not allow non-mxc content URLs - ?.takeIf { it.isValidMatrixContentUrl() } + ?.takeIf { it.isMxcUrl() } ?.let { resolve( contentUrl = it, @@ -45,7 +45,7 @@ internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectio override fun resolveThumbnail(contentUrl: String?, width: Int, height: Int, method: ContentUrlResolver.ThumbnailMethod): String? { return contentUrl // do not allow non-mxc content URLs - ?.takeIf { it.isValidMatrixContentUrl() } + ?.takeIf { it.isMxcUrl() } ?.let { resolve( contentUrl = it, @@ -58,7 +58,7 @@ internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectio private fun resolve(contentUrl: String, prefix: String, params: String = ""): String? { - var serverAndMediaId = contentUrl.removePrefix(MATRIX_CONTENT_URI_SCHEME) + var serverAndMediaId = contentUrl.removePrefix(MatrixUrls.MATRIX_CONTENT_URI_SCHEME) val fragmentOffset = serverAndMediaId.indexOf("#") var fragment = "" if (fragmentOffset >= 0) { @@ -68,8 +68,4 @@ internal class DefaultContentUrlResolver @Inject constructor(homeServerConnectio return baseUrl + prefix + serverAndMediaId + params + fragment } - - private fun String.isValidMatrixContentUrl(): Boolean { - return startsWith(MATRIX_CONTENT_URI_SCHEME) - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt index 6a4dd26392..bdebb0addf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt @@ -67,8 +67,8 @@ internal class FileUploader @Inject constructor( // Check size limit val maxUploadFileSize = homeServerCapabilitiesService.getHomeServerCapabilities().maxUploadFileSize - if (maxUploadFileSize != HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN - && file.length() > maxUploadFileSize) { + if (maxUploadFileSize != HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN && + file.length() > maxUploadFileSize) { // Known limitation and file too big for the server, save the pain to upload it throw Failure.ServerError( error = MatrixError( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index f14c85cf80..11c200c54b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -63,8 +63,8 @@ private data class NewAttachmentAttributes( * Possible previous worker: None * Possible next worker : Always [MultipleEventSendingDispatcherWorker] */ -internal class UploadContentWorker(val context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { +internal class UploadContentWorker(val context: Context, params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( @@ -157,10 +157,10 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter params.attachment.size ) - if (attachment.type == ContentAttachmentData.Type.IMAGE + if (attachment.type == ContentAttachmentData.Type.IMAGE && // Do not compress gif - && attachment.mimeType != MimeTypes.Gif - && params.compressBeforeSending) { + attachment.mimeType != MimeTypes.Gif && + params.compressBeforeSending) { notifyTracker(params) { contentUploadStateTracker.setCompressingImage(it) } fileToUpload = imageCompressor.compress(workingFile, MAX_IMAGE_SIZE, MAX_IMAGE_SIZE) @@ -177,10 +177,10 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter } } .also { filesToDelete.add(it) } - } else if (attachment.type == ContentAttachmentData.Type.VIDEO + } else if (attachment.type == ContentAttachmentData.Type.VIDEO && // Do not compress gif - && attachment.mimeType != MimeTypes.Gif - && params.compressBeforeSending) { + attachment.mimeType != MimeTypes.Gif && + params.compressBeforeSending) { fileToUpload = videoCompressor.compress(workingFile, object : ProgressListener { override fun onProgress(progress: Int, total: Int) { notifyTracker(params) { contentUploadStateTracker.setCompressingVideo(it, progress.toFloat()) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt new file mode 100644 index 0000000000..76d956f9a5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/displayname/DisplayNameResolver.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2021 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.displayname + +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.util.MatrixItem +import javax.inject.Inject + +internal class DisplayNameResolver @Inject constructor( + private val matrixConfiguration: MatrixConfiguration +) { + fun getBestName(matrixItem: MatrixItem): String { + return if (matrixItem is MatrixItem.GroupItem || matrixItem is MatrixItem.RoomAliasItem) { + // Best name is the id, and we keep the displayName of the room for the case we need the first letter + matrixItem.id + } else { + matrixItem.displayName?.takeIf { it.isNotBlank() } + ?: matrixConfiguration.matrixItemDisplayNameFallbackProvider?.getDefaultName(matrixItem) + ?: matrixItem.id + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/DefaultFilterRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/DefaultFilterRepository.kt index 095c39a485..1d1bb0e715 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/DefaultFilterRepository.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/DefaultFilterRepository.kt @@ -17,14 +17,14 @@ package org.matrix.android.sdk.internal.session.filter import com.zhuinden.monarchy.Monarchy +import io.realm.Realm +import io.realm.kotlin.where import org.matrix.android.sdk.internal.database.model.FilterEntity import org.matrix.android.sdk.internal.database.model.FilterEntityFields import org.matrix.android.sdk.internal.database.query.get import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.util.awaitTransaction -import io.realm.Realm -import io.realm.kotlin.where import javax.inject.Inject internal class DefaultFilterRepository @Inject constructor(@SessionDatabase private val monarchy: Monarchy) : FilterRepository { @@ -33,9 +33,9 @@ internal class DefaultFilterRepository @Inject constructor(@SessionDatabase priv return Realm.getInstance(monarchy.realmConfiguration).use { realm -> val filterEntity = FilterEntity.get(realm) // Filter has changed, or no filter Id yet - filterEntity == null - || filterEntity.filterBodyJson != filter.toJSONString() - || filterEntity.filterId.isBlank() + filterEntity == null || + filterEntity.filterBodyJson != filter.toJSONString() || + filterEntity.filterId.isBlank() }.also { hasChanged -> if (hasChanged) { // Filter is new or has changed, store it and reset the filter Id. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt index 1be62304a1..37630ef8ba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt @@ -50,10 +50,10 @@ data class EventFilter( @Json(name = "not_types") val notTypes: List? = null ) { fun hasData(): Boolean { - return limit != null - || senders != null - || notSenders != null - || types != null - || notTypes != null + return limit != null || + senders != null || + notSenders != null || + types != null || + notTypes != null } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt index d6089f9f5b..7047d38260 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt @@ -73,14 +73,14 @@ data class RoomEventFilter( } fun hasData(): Boolean { - return (limit != null - || notSenders != null - || notTypes != null - || senders != null - || types != null - || rooms != null - || notRooms != null - || containsUrl != null - || lazyLoadMembers != null) + return (limit != null || + notSenders != null || + notTypes != null || + senders != null || + types != null || + rooms != null || + notRooms != null || + containsUrl != null || + lazyLoadMembers != null) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt index fbf22fde51..2c56a30d39 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt @@ -59,12 +59,12 @@ data class RoomFilter( ) { fun hasData(): Boolean { - return (notRooms != null - || rooms != null - || ephemeral != null - || includeLeave != null - || state != null - || timeline != null - || accountData != null) + return (notRooms != null || + rooms != null || + ephemeral != null || + includeLeave != null || + state != null || + timeline != null || + accountData != null) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt index 425d6a9aca..8dc5f3931d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroupService.kt @@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.session.group import androidx.lifecycle.LiveData import com.zhuinden.monarchy.Monarchy +import io.realm.Realm +import io.realm.RealmQuery import org.matrix.android.sdk.api.session.group.Group import org.matrix.android.sdk.api.session.group.GroupService import org.matrix.android.sdk.api.session.group.GroupSummaryQueryParams @@ -30,8 +32,6 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.query.process import org.matrix.android.sdk.internal.util.fetchCopyMap -import io.realm.Realm -import io.realm.RealmQuery import javax.inject.Inject internal class DefaultGroupService @Inject constructor(@SessionDatabase private val monarchy: Monarchy, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt index d6b9363d54..338f43bdbb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GetGroupDataWorker.kt @@ -28,8 +28,8 @@ import javax.inject.Inject * Possible previous worker: None * Possible next worker : None */ -internal class GetGroupDataWorker(context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { +internal class GetGroupDataWorker(context: Context, params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerPinger.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerPinger.kt index bb526adf4a..70e1e551aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerPinger.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/HomeServerPinger.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.homeserver +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.TaskExecutor -import kotlinx.coroutines.launch import javax.inject.Inject internal class HomeServerPinger @Inject constructor(private val taskExecutor: TaskExecutor, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt index acd163450c..da37948cd4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt @@ -320,12 +320,12 @@ internal class DefaultIdentityService @Inject constructor( } private fun Throwable.isInvalidToken(): Boolean { - return this is Failure.ServerError - && httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */ + return this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */ } private fun Throwable.isTermsNotSigned(): Boolean { - return this is Failure.ServerError - && httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */ - && error.code == MatrixError.M_TERMS_NOT_SIGNED + return this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_FORBIDDEN && /* 403 */ + error.code == MatrixError.M_TERMS_NOT_SIGNED } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/EnsureIdentityToken.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/EnsureIdentityToken.kt index 5e1434403e..657d1f3ac7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/EnsureIdentityToken.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/EnsureIdentityToken.kt @@ -17,13 +17,13 @@ package org.matrix.android.sdk.internal.session.identity import dagger.Lazy +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.session.identity.data.IdentityStore import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask import org.matrix.android.sdk.internal.task.Task -import okhttp3.OkHttpClient import javax.inject.Inject internal interface EnsureIdentityTokenTask : Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt index 114695062c..f6ef370f8d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityBulkLookupTask.kt @@ -117,8 +117,8 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor( return withOlmUtility { olmUtility -> threePids.map { threePid -> base64ToBase64Url( - olmUtility.sha256(threePid.value.lowercase(Locale.ROOT) - + " " + threePid.toMedium() + " " + pepper) + olmUtility.sha256(threePid.value.lowercase(Locale.ROOT) + + " " + threePid.toMedium() + " " + pepper) ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt index 4d664b76be..19e602d7a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt @@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.session.identity import dagger.Binds import dagger.Module import dagger.Provides +import io.realm.RealmConfiguration +import okhttp3.OkHttpClient import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.IdentityDatabase @@ -32,8 +34,6 @@ import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.identity.data.IdentityStore import org.matrix.android.sdk.internal.session.identity.db.IdentityRealmModule import org.matrix.android.sdk.internal.session.identity.db.RealmIdentityStore -import io.realm.RealmConfiguration -import okhttp3.OkHttpClient import org.matrix.android.sdk.internal.session.identity.db.RealmIdentityStoreMigration import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntity.kt index be68e17a49..fcc91b0121 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntity.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.identity.db -import org.matrix.android.sdk.api.session.identity.ThreePid -import org.matrix.android.sdk.api.session.identity.toMedium import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.api.session.identity.ThreePid +import org.matrix.android.sdk.api.session.identity.toMedium internal open class IdentityPendingBindingEntity( @PrimaryKey var threePid: String = "", diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntityQuery.kt index aa2f4dd5b2..8d4afc7beb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/IdentityPendingBindingEntityQuery.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.identity.db -import org.matrix.android.sdk.api.session.identity.ThreePid import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.api.session.identity.ThreePid internal fun IdentityPendingBindingEntity.Companion.get(realm: Realm, threePid: ThreePid): IdentityPendingBindingEntity? { return realm.where() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStore.kt index 2fa3fc0cfb..ce8b78b2d0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStore.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.session.identity.db +import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.di.IdentityDatabase import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.session.identity.data.IdentityPendingBinding import org.matrix.android.sdk.internal.session.identity.data.IdentityData +import org.matrix.android.sdk.internal.session.identity.data.IdentityPendingBinding import org.matrix.android.sdk.internal.session.identity.data.IdentityStore import org.matrix.android.sdk.internal.session.identity.model.IdentityHashDetailResponse -import io.realm.Realm -import io.realm.RealmConfiguration import javax.inject.Inject @SessionScope diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt index 6dac9bffd0..079b0d0115 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt @@ -23,8 +23,8 @@ import org.matrix.android.sdk.internal.session.SessionScope import javax.inject.Inject @SessionScope -internal class DefaultSyncStatusService @Inject constructor() - : SyncStatusService, +internal class DefaultSyncStatusService @Inject constructor() : + SyncStatusService, ProgressReporter { private val status = MutableLiveData() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt index b654b8610d..30b1589169 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManager.kt @@ -22,6 +22,9 @@ import androidx.lifecycle.LifecycleRegistry import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.SessionLifecycleObserver +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService @@ -30,12 +33,9 @@ import org.matrix.android.sdk.api.session.widgets.model.WidgetType import org.matrix.android.sdk.internal.database.model.WellknownIntegrationManagerConfigEntity import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.extensions.observeNotNull -import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent -import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence import timber.log.Timber @@ -58,8 +58,8 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri @SessionDatabase private val monarchy: Monarchy, private val updateUserAccountDataTask: UpdateUserAccountDataTask, private val accountDataDataSource: UserAccountDataDataSource, - private val widgetFactory: WidgetFactory) - : SessionLifecycleObserver { + private val widgetFactory: WidgetFactory) : + SessionLifecycleObserver { private val currentConfigs = ArrayList() private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManagerConfigExtractor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManagerConfigExtractor.kt index f7a8b68515..8c63dbeb0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManagerConfigExtractor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/integrationmanager/IntegrationManagerConfigExtractor.kt @@ -29,9 +29,9 @@ internal class IntegrationManagerConfigExtractor @Inject constructor() { (config as? Map<*, *>)?.let { map -> val apiUrl = map["api_url"] as? String val uiUrl = map["ui_url"] as? String ?: apiUrl - if (apiUrl != null - && apiUrl.startsWith("https://") - && uiUrl!!.startsWith("https://")) { + if (apiUrl != null && + apiUrl.startsWith("https://") && + uiUrl!!.startsWith("https://")) { return WellknownIntegrationManagerConfigEntity( apiUrl = apiUrl, uiUrl = uiUrl diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt index d1fb5b98ff..85a126ef78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/media/UrlsExtractor.kt @@ -33,9 +33,9 @@ internal class UrlsExtractor @Inject constructor() { return event.takeIf { it.root.getClearType() == EventType.MESSAGE } ?.getLastMessageContent() ?.takeIf { - it.msgType == MessageType.MSGTYPE_TEXT - || it.msgType == MessageType.MSGTYPE_NOTICE - || it.msgType == MessageType.MSGTYPE_EMOTE + it.msgType == MessageType.MSGTYPE_TEXT || + it.msgType == MessageType.MSGTYPE_NOTICE || + it.msgType == MessageType.MSGTYPE_EMOTE } ?.let { messageContent -> if (event.isReply()) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 0ece07fc15..1321f8dd62 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk.internal.session.notification import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.task.Task import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt index b90a2435f7..afff0f3515 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/DefaultOpenIdService.kt @@ -20,7 +20,7 @@ import org.matrix.android.sdk.api.session.openid.OpenIdService import org.matrix.android.sdk.api.session.openid.OpenIdToken import javax.inject.Inject -internal class DefaultOpenIdService @Inject constructor(private val getOpenIdTokenTask: GetOpenIdTokenTask): OpenIdService { +internal class DefaultOpenIdService @Inject constructor(private val getOpenIdTokenTask: GetOpenIdTokenTask) : OpenIdService { override suspend fun getOpenIdToken(): OpenIdToken { return getOpenIdTokenTask.execute(Unit) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 134da4ce51..144ebb5404 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -18,33 +18,29 @@ package org.matrix.android.sdk.internal.session.permalinks import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.permalinks.PermalinkService -import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE import javax.inject.Inject internal class DefaultPermalinkService @Inject constructor( private val permalinkFactory: PermalinkFactory ) : PermalinkService { - override fun createPermalink(event: Event): String? { - return permalinkFactory.createPermalink(event) + override fun createPermalink(event: Event, forceMatrixTo: Boolean): String? { + return permalinkFactory.createPermalink(event, forceMatrixTo) } - override fun createPermalink(id: String): String? { - return permalinkFactory.createPermalink(id) + override fun createPermalink(id: String, forceMatrixTo: Boolean): String? { + return permalinkFactory.createPermalink(id, forceMatrixTo) } - override fun createRoomPermalink(roomId: String, viaServers: List?): String? { - return permalinkFactory.createRoomPermalink(roomId, viaServers) + override fun createRoomPermalink(roomId: String, viaServers: List?, forceMatrixTo: Boolean): String? { + return permalinkFactory.createRoomPermalink(roomId, viaServers, forceMatrixTo) } - override fun createPermalink(roomId: String, eventId: String): String { - return permalinkFactory.createPermalink(roomId, eventId) + override fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String { + return permalinkFactory.createPermalink(roomId, eventId, forceMatrixTo) } override fun getLinkedId(url: String): String? { - return url - .takeIf { it.startsWith(MATRIX_TO_URL_BASE) } - ?.substring(MATRIX_TO_URL_BASE.length) - ?.substringBeforeLast("?") + return permalinkFactory.getLinkedId(url) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt index 639e45582a..39c1ddfdce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/PermalinkFactory.kt @@ -16,7 +16,11 @@ package org.matrix.android.sdk.internal.session.permalinks +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.permalinks.PermalinkData +import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE import org.matrix.android.sdk.internal.di.UserId import javax.inject.Inject @@ -24,28 +28,44 @@ import javax.inject.Inject internal class PermalinkFactory @Inject constructor( @UserId private val userId: String, - private val viaParameterFinder: ViaParameterFinder + private val viaParameterFinder: ViaParameterFinder, + private val matrixConfiguration: MatrixConfiguration ) { - fun createPermalink(event: Event): String? { + fun createPermalink(event: Event, forceMatrixTo: Boolean): String? { if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) { return null } - return createPermalink(event.roomId, event.eventId) + return createPermalink(event.roomId, event.eventId, forceMatrixTo) } - fun createPermalink(id: String): String? { - return if (id.isEmpty()) { - null - } else MATRIX_TO_URL_BASE + escape(id) + fun createPermalink(id: String, forceMatrixTo: Boolean): String? { + return when { + id.isEmpty() -> null + !useClientFormat(forceMatrixTo) -> MATRIX_TO_URL_BASE + escape(id) + else -> { + buildString { + append(matrixConfiguration.clientPermalinkBaseUrl) + when { + MatrixPatterns.isRoomId(id) || MatrixPatterns.isRoomAlias(id) -> append(ROOM_PATH) + MatrixPatterns.isUserId(id) -> append(USER_PATH) + MatrixPatterns.isGroupId(id) -> append(GROUP_PATH) + } + append(escape(id)) + } + } + } } - fun createRoomPermalink(roomId: String, via: List? = null): String? { + fun createRoomPermalink(roomId: String, via: List? = null, forceMatrixTo: Boolean): String? { return if (roomId.isEmpty()) { null } else { buildString { - append(MATRIX_TO_URL_BASE) + append(baseUrl(forceMatrixTo)) + if (useClientFormat(forceMatrixTo)) { + append(ROOM_PATH) + } append(escape(roomId)) append( via?.takeIf { it.isNotEmpty() }?.let { viaParameterFinder.asUrlViaParameters(it) } @@ -55,16 +75,34 @@ internal class PermalinkFactory @Inject constructor( } } - fun createPermalink(roomId: String, eventId: String): String { - return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + viaParameterFinder.computeViaParams(userId, roomId) + fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String { + return buildString { + append(baseUrl(forceMatrixTo)) + if (useClientFormat(forceMatrixTo)) { + append(ROOM_PATH) + } + append(escape(roomId)) + append("/") + append(escape(eventId)) + append(viaParameterFinder.computeViaParams(userId, roomId)) + } } fun getLinkedId(url: String): String? { - val isSupported = url.startsWith(MATRIX_TO_URL_BASE) - - return if (isSupported) { - url.substring(MATRIX_TO_URL_BASE.length) - } else null + val clientBaseUrl = matrixConfiguration.clientPermalinkBaseUrl + return when { + url.startsWith(MATRIX_TO_URL_BASE) -> url.substring(MATRIX_TO_URL_BASE.length) + clientBaseUrl != null && url.startsWith(clientBaseUrl) -> { + when (PermalinkParser.parse(url)) { + is PermalinkData.GroupLink -> url.substring(clientBaseUrl.length + GROUP_PATH.length) + is PermalinkData.RoomLink -> url.substring(clientBaseUrl.length + ROOM_PATH.length) + is PermalinkData.UserLink -> url.substring(clientBaseUrl.length + USER_PATH.length) + else -> null + } + } + else -> null + } + ?.substringBeforeLast("?") } /** @@ -86,4 +124,28 @@ internal class PermalinkFactory @Inject constructor( private fun unescape(id: String): String { return id.replace("%2F", "/") } + + /** + * Get the permalink base URL according to the potential one in [MatrixConfiguration.clientPermalinkBaseUrl] + * and the [forceMatrixTo] parameter. + * + * @param forceMatrixTo whether we should force using matrix.to base URL. + * + * @return the permalink base URL. + */ + private fun baseUrl(forceMatrixTo: Boolean): String { + return matrixConfiguration.clientPermalinkBaseUrl + ?.takeUnless { forceMatrixTo } + ?: MATRIX_TO_URL_BASE + } + + private fun useClientFormat(forceMatrixTo: Boolean): Boolean { + return !forceMatrixTo && matrixConfiguration.clientPermalinkBaseUrl != null + } + + companion object { + private const val ROOM_PATH = "room/" + private const val USER_PATH = "user/" + private const val GROUP_PATH = "group/" + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt index 5f063365e0..6ff4efaf11 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/FinalizeAddingThreePidTask.kt @@ -17,12 +17,12 @@ package org.matrix.android.sdk.internal.session.profile import com.zhuinden.monarchy.Monarchy +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.auth.registration.handleUIA -import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.internal.database.model.PendingThreePidEntity import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.di.SessionDatabase @@ -71,8 +71,8 @@ internal class DefaultFinalizeAddingThreePidTask @Inject constructor( } true } catch (throwable: Throwable) { - if (params.userInteractiveAuthInterceptor == null - || !handleUIA( + if (params.userInteractiveAuthInterceptor == null || + !handleUIA( failure = throwable, interceptor = params.userInteractiveAuthInterceptor, retryBlock = { authUpdate -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPusherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPusherWorker.kt index 079fd1d3e5..63fd855c08 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPusherWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/AddPusherWorker.kt @@ -33,8 +33,8 @@ import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker import org.matrix.android.sdk.internal.worker.SessionWorkerParams import javax.inject.Inject -internal class AddPusherWorker(context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { +internal class AddPusherWorker(context: Context, params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt index 3a2ebf40c2..057c309078 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/RemovePusherTask.kt @@ -17,16 +17,16 @@ package org.matrix.android.sdk.internal.session.pushers import com.zhuinden.monarchy.Monarchy +import io.realm.Realm import org.matrix.android.sdk.api.session.pushers.PusherState import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.PusherEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import io.realm.Realm -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import javax.inject.Inject internal interface RemovePusherTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index f69949cbb6..5b2499c130 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -93,13 +93,15 @@ internal class DefaultRoomService @Inject constructor( return roomSummaryDataSource.getRoomSummariesLive(queryParams) } - override fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config, sortOrder: RoomSortOrder) - : LiveData> { + override fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config, + sortOrder: RoomSortOrder): LiveData> { return roomSummaryDataSource.getSortedPagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder) } - override fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config, sortOrder: RoomSortOrder) - : UpdatableLivePageResult { + override fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config, + sortOrder: RoomSortOrder): UpdatableLivePageResult { return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index c7e09e5954..5a1eb190a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -131,8 +131,8 @@ internal class EventRelationsAggregationProcessor @Inject constructor( EventType.ENCRYPTED -> { // Relation type is in clear val encryptedEventContent = event.content.toModel() - if (encryptedEventContent?.relatesTo?.type == RelationType.REPLACE - || encryptedEventContent?.relatesTo?.type == RelationType.RESPONSE + if (encryptedEventContent?.relatesTo?.type == RelationType.REPLACE || + encryptedEventContent?.relatesTo?.type == RelationType.RESPONSE ) { event.getClearContent().toModel()?.let { if (encryptedEventContent.relatesTo.type == RelationType.REPLACE) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 98e7659238..efc5166a0c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -216,22 +216,6 @@ internal interface RoomAPI { @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state") suspend fun getRoomState(@Path("roomId") roomId: String): List - /** - * Send a relation event to a room. - * - * @param txId the transaction Id - * @param roomId the room id - * @param eventType the event type - * @param content the event content - */ - @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}") - suspend fun sendRelation(@Path("roomId") roomId: String, - @Path("parent_id") parentId: String, - @Path("relation_type") relationType: String, - @Path("event_type") eventType: String, - @Body content: Content? - ): SendResponse - /** * Paginate relations for event based in normal topological order * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DefaultAliasService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DefaultAliasService.kt index 8f58094a2a..73a3b285e9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DefaultAliasService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/DefaultAliasService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.session.room.alias import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.session.room.alias.AliasService internal class DefaultAliasService @AssistedInject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/call/DefaultRoomCallService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/call/DefaultRoomCallService.kt index 9bde5054f6..675034531d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/call/DefaultRoomCallService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/call/DefaultRoomCallService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.session.room.call import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.room.call.RoomCallService import org.matrix.android.sdk.internal.session.room.RoomGetter diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 9bb3899f2f..84261e6ebf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -77,9 +77,9 @@ internal class CreateRoomBodyBuilder @Inject constructor( buildHistoryVisibilityEvent(params), buildAvatarEvent(params), buildGuestAccess(params) - ) - + params.featurePreset?.setupInitialStates().orEmpty() - + buildCustomInitialStates(params) + ) + + params.featurePreset?.setupInitialStates().orEmpty() + + buildCustomInitialStates(params) ) .takeIf { it.isNotEmpty() } @@ -154,8 +154,8 @@ internal class CreateRoomBodyBuilder @Inject constructor( * Add the crypto algorithm to the room creation parameters. */ private suspend fun buildEncryptionWithAlgorithmEvent(params: CreateRoomParams): Event? { - if (params.algorithm == null - && canEnableEncryption(params)) { + if (params.algorithm == null && + canEnableEncryption(params)) { // Enable the encryption params.enableEncryption() } @@ -173,13 +173,13 @@ internal class CreateRoomBodyBuilder @Inject constructor( } private suspend fun canEnableEncryption(params: CreateRoomParams): Boolean { - return params.enableEncryptionIfInvitedUsersSupportIt + return params.enableEncryptionIfInvitedUsersSupportIt && // Parity with web, enable if users have encryption ready devices // for now remove checks on cross signing and 3pid invites // && crossSigningService.isCrossSigningVerified() - && params.invite3pids.isEmpty() - && params.invitedUserIds.isNotEmpty() - && params.invitedUserIds.let { userIds -> + params.invite3pids.isEmpty() && + params.invitedUserIds.isNotEmpty() && + params.invitedUserIds.let { userIds -> val keys = deviceListManager.downloadKeys(userIds, forceDownload = false) userIds.all { userId -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt index 518f0a0a6d..ac6e0562b0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt @@ -81,13 +81,13 @@ internal class DefaultCreateRoomTask @Inject constructor( } } catch (throwable: Throwable) { if (throwable is Failure.ServerError) { - if (throwable.httpCode == 403 - && throwable.error.code == MatrixError.M_FORBIDDEN - && throwable.error.message.startsWith("Federation denied with")) { + if (throwable.httpCode == 403 && + throwable.error.code == MatrixError.M_FORBIDDEN && + throwable.error.message.startsWith("Federation denied with")) { throw CreateRoomFailure.CreatedWithFederationFailure(throwable.error) - } else if (throwable.httpCode == 400 - && throwable.error.code == MatrixError.M_UNKNOWN - && throwable.error.message == "Invalid characters in room alias") { + } else if (throwable.httpCode == 400 && + throwable.error.code == MatrixError.M_UNKNOWN && + throwable.error.message == "Invalid characters in room alias") { throw CreateRoomFailure.AliasError(RoomAliasError.AliasInvalid) } } @@ -138,8 +138,8 @@ internal class DefaultCreateRoomTask @Inject constructor( * @return true if it is a direct chat */ private fun CreateRoomParams.isDirect(): Boolean { - return preset == CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT - && isDirect == true + return preset == CreateRoomPreset.PRESET_TRUSTED_PRIVATE_CHAT && + isDirect == true } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt index cc66a0a2d2..eb966b684c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/RoomCreateEventProcessor.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.create +import io.realm.Realm 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.toModel @@ -25,7 +26,6 @@ import org.matrix.android.sdk.internal.database.model.EventInsertType import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor -import io.realm.Realm import javax.inject.Inject internal class RoomCreateEventProcessor @Inject constructor() : EventInsertLiveProcessor { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/draft/DefaultDraftService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/draft/DefaultDraftService.kt index 1d4ab6d516..046f8ba8ba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/draft/DefaultDraftService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/draft/DefaultDraftService.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk.internal.session.room.draft import androidx.lifecycle.LiveData import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.room.send.DraftService import org.matrix.android.sdk.api.session.room.send.UserDraft diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt index 41e891f78e..204deb72b4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt @@ -17,10 +17,12 @@ package org.matrix.android.sdk.internal.session.room.membership import androidx.lifecycle.LiveData -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import dagger.assisted.AssistedFactory import com.zhuinden.monarchy.Monarchy +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import io.realm.Realm +import io.realm.RealmQuery import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.room.members.MembershipService import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams @@ -38,8 +40,6 @@ import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomT import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoomTask import org.matrix.android.sdk.internal.session.room.membership.threepid.InviteThreePidTask import org.matrix.android.sdk.internal.util.fetchCopied -import io.realm.Realm -import io.realm.RealmQuery internal class DefaultMembershipService @AssistedInject constructor( @Assisted private val roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt index 3aa812d93d..5e77dd157a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrNull import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import javax.inject.Inject /** @@ -40,6 +41,7 @@ import javax.inject.Inject */ internal class RoomDisplayNameResolver @Inject constructor( matrixConfiguration: MatrixConfiguration, + private val displayNameResolver: DisplayNameResolver, @UserId private val userId: String ) { @@ -83,7 +85,8 @@ internal class RoomDisplayNameResolver @Inject constructor( activeMembers.where() .equalTo(RoomMemberSummaryEntityFields.USER_ID, it) .findFirst() - ?.getBestName() + ?.toMatrixItem() + ?.let { matrixItem -> displayNameResolver.getBestName(matrixItem) } } ?: roomDisplayNameFallbackProvider.getNameForRoomInvite() } else if (roomEntity?.membership == Membership.JOIN) { @@ -109,7 +112,7 @@ internal class RoomDisplayNameResolver @Inject constructor( // Get left members if any val leftMembersNames = roomMembers.queryLeftRoomMembersEvent() .findAll() - .map { it.getBestName() } + .map { displayNameResolver.getBestName(it.toMatrixItem()) } roomDisplayNameFallbackProvider.getNameForEmptyRoom(roomSummary?.isDirect.orFalse(), leftMembersNames) } 1 -> { @@ -157,7 +160,7 @@ internal class RoomDisplayNameResolver @Inject constructor( roomMemberHelper: RoomMemberHelper): String { val isUnique = roomMemberHelper.isUniqueDisplayName(roomMemberSummary.displayName) return if (isUnique) { - roomMemberSummary.getBestName() + displayNameResolver.getBestName(roomMemberSummary.toMatrixItem()) } else { "${roomMemberSummary.displayName} (${roomMemberSummary.userId})" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt index 209a904fad..82fea237db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt @@ -43,7 +43,7 @@ internal interface JoinRoomTask : Task { val roomIdOrAlias: String, val reason: String?, val viaServers: List = emptyList(), - val thirdPartySigned : SignInvitationResult? = null + val thirdPartySigned: SignInvitationResult? = null ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/DefaultRoomPushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/DefaultRoomPushRuleService.kt index 5486d96e28..8f1aefb731 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/DefaultRoomPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/DefaultRoomPushRuleService.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.session.room.notification import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import dagger.assisted.AssistedFactory import com.zhuinden.monarchy.Monarchy +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.pushrules.RuleScope import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService @@ -31,8 +31,8 @@ import org.matrix.android.sdk.internal.di.SessionDatabase internal class DefaultRoomPushRuleService @AssistedInject constructor(@Assisted private val roomId: String, private val setRoomNotificationStateTask: SetRoomNotificationStateTask, - @SessionDatabase private val monarchy: Monarchy) - : RoomPushRuleService { + @SessionDatabase private val monarchy: Monarchy) : + RoomPushRuleService { @AssistedFactory interface Factory { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/SetRoomNotificationStateTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/SetRoomNotificationStateTask.kt index 9cea1fe425..feb8c27b09 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/SetRoomNotificationStateTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/SetRoomNotificationStateTask.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.notification import com.zhuinden.monarchy.Monarchy +import io.realm.Realm import org.matrix.android.sdk.api.pushrules.RuleScope import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.internal.database.model.PushRuleEntity @@ -25,7 +26,6 @@ import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.pushers.AddPushRuleTask import org.matrix.android.sdk.internal.session.pushers.RemovePushRuleTask import org.matrix.android.sdk.internal.task.Task -import io.realm.Realm import javax.inject.Inject internal interface SetRoomNotificationStateTask : Task { @@ -37,8 +37,8 @@ internal interface SetRoomNotificationStateTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt deleted file mode 100644 index 5d0879d706..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2020 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.relation - -import android.content.Context -import androidx.work.WorkerParameters -import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.api.failure.Failure -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent -import org.matrix.android.sdk.api.session.room.model.relation.ReactionInfo -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver -import org.matrix.android.sdk.internal.network.executeRequest -import org.matrix.android.sdk.internal.session.SessionComponent -import org.matrix.android.sdk.internal.session.room.RoomAPI -import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository -import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -import org.matrix.android.sdk.internal.worker.SessionWorkerParams -import javax.inject.Inject - -// TODO This is not used. Delete? -internal class SendRelationWorker(context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { - - @JsonClass(generateAdapter = true) - internal data class Params( - override val sessionId: String, - val roomId: String, - val eventId: String, - val relationType: String? = null, - override val lastFailureMessage: String? = null - ) : SessionWorkerParams - - @Inject lateinit var roomAPI: RoomAPI - @Inject lateinit var globalErrorReceiver: GlobalErrorReceiver - @Inject lateinit var localEchoRepository: LocalEchoRepository - - override fun injectWith(injector: SessionComponent) { - injector.inject(this) - } - - override suspend fun doSafeWork(params: Params): Result { - val localEvent = localEchoRepository.getUpToDateEcho(params.eventId) - if (localEvent?.eventId == null) { - return Result.failure() - } - val relationContent = localEvent.content.toModel() - ?: return Result.failure() - val relatedEventId = relationContent.relatesTo?.eventId ?: return Result.failure() - val relationType = (relationContent.relatesTo as? ReactionInfo)?.type ?: params.relationType - ?: return Result.failure() - return try { - sendRelation(params.roomId, relationType, relatedEventId, localEvent) - Result.success() - } catch (exception: Throwable) { - when (exception) { - is Failure.NetworkConnection -> Result.retry() - else -> { - // TODO mark as failed to send? - // always return success, or the chain will be stuck for ever! - Result.success() - } - } - } - } - - override fun buildErrorParams(params: Params, message: String): Params { - return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) - } - - private suspend fun sendRelation(roomId: String, relationType: String, relatedEventId: String, localEvent: Event) { - executeRequest(globalErrorReceiver) { - roomAPI.sendRelation( - roomId = roomId, - parentId = relatedEventId, - relationType = relationType, - eventType = localEvent.type!!, - content = localEvent.content - ) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt index 32d6c5aa7e..d0ab430dad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.relation import com.zhuinden.monarchy.Monarchy +import io.realm.Realm import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.ReactionAggregatedSummaryEntityFields @@ -23,7 +24,6 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task -import io.realm.Realm import javax.inject.Inject internal interface UpdateQuickReactionTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt index add17a9fa5..c961f718ef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/reporting/DefaultReportingService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.session.room.reporting import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.session.room.reporting.ReportingService internal class DefaultReportingService @AssistedInject constructor(@Assisted private val roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt index 6dbb71e096..177c98541c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt @@ -22,9 +22,10 @@ import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequest import androidx.work.Operation import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage @@ -130,7 +131,7 @@ internal class DefaultSendService @AssistedInject constructor( val messageContent = clearContent?.toModel() as? MessageWithAttachmentContent ?: return NoOpCancellable val url = messageContent.getFileUrl() ?: return NoOpCancellable - if (url.startsWith("mxc://")) { + if (url.isMxcUrl()) { // We need to resend only the message as the attachment is ok localEchoRepository.updateSendState(localEcho.eventId, roomId, SendState.UNSENT) return sendEvent(localEcho.root) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index c610326a94..8dd0c59387 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -165,8 +165,8 @@ internal class LocalEchoEventFactory @Inject constructor( newBodyAutoMarkdown: Boolean, msgType: String, compatibilityText: String): Event { - val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "") - val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it) } ?: "" + val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "", false) + val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it, false) } ?: "" val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply()) val replyFormatted = REPLY_PATTERN.format( @@ -350,9 +350,9 @@ internal class LocalEchoEventFactory @Inject constructor( autoMarkdown: Boolean): Event? { // Fallbacks and event representation // TODO Add error/warning logs when any of this is null - val permalink = permalinkFactory.createPermalink(eventReplied.root) ?: return null + val permalink = permalinkFactory.createPermalink(eventReplied.root, false) ?: return null val userId = eventReplied.root.senderId ?: return null - val userLink = permalinkFactory.createPermalink(userId) ?: return null + val userLink = permalinkFactory.createPermalink(userId, false) ?: return null val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) val replyFormatted = REPLY_PATTERN.format( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt index e889f1a61b..16a9eba363 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt @@ -38,8 +38,8 @@ import javax.inject.Inject * Possible previous worker: Always [UploadContentWorker] * Possible next worker : None, but it will post new work to send events, encrypted or not */ -internal class MultipleEventSendingDispatcherWorker(context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { +internal class MultipleEventSendingDispatcherWorker(context: Context, params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt index 306f865408..b4436bfcbf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt @@ -32,8 +32,8 @@ import javax.inject.Inject * Possible previous worker: None * Possible next worker : None */ -internal class RedactEventWorker(context: Context, params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { +internal class RedactEventWorker(context: Context, params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt index cd7911910d..8b7fe4b907 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt @@ -39,8 +39,8 @@ import javax.inject.Inject * Possible next worker : None */ internal class SendEventWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { + params: WorkerParameters) : + SessionSafeCoroutineWorker(context, params, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt index faf966edf4..33cb0db243 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.send.pills import android.text.SpannableString import org.matrix.android.sdk.api.session.room.send.MatrixItemSpan +import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import java.util.Collections import javax.inject.Inject @@ -25,7 +26,8 @@ import javax.inject.Inject * formatted text to send them as a Matrix messages. */ internal class TextPillsUtils @Inject constructor( - private val mentionLinkSpecComparator: MentionLinkSpecComparator + private val mentionLinkSpecComparator: MentionLinkSpecComparator, + private val displayNameResolver: DisplayNameResolver ) { /** @@ -63,7 +65,7 @@ internal class TextPillsUtils @Inject constructor( // append text before pill append(text, currIndex, start) // append the pill - append(String.format(template, urlSpan.matrixItem.id, urlSpan.matrixItem.getBestName())) + append(String.format(template, urlSpan.matrixItem.id, displayNameResolver.getBestName(urlSpan.matrixItem))) currIndex = end } // append text after the last pill diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt index cd5bf575db..050e321b9c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.room.send.queue +import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.util.Cancelable -import org.matrix.android.sdk.api.session.SessionLifecycleObserver -internal interface EventSenderProcessor: SessionLifecycleObserver { +internal interface EventSenderProcessor : SessionLifecycleObserver { fun postEvent(event: Event): Cancelable 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 4a6e27b7c0..30014f4539 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 @@ -34,6 +34,8 @@ import org.matrix.android.sdk.api.session.room.model.VersioningState import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary +import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications import org.matrix.android.sdk.internal.crypto.EventDecryptor import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService @@ -63,8 +65,6 @@ import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataD import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncSummary -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncUnreadNotifications import timber.log.Timber import javax.inject.Inject import kotlin.system.measureTimeMillis @@ -105,8 +105,8 @@ internal class RoomSummaryUpdater @Inject constructor( } // Hard to filter from the app now we use PagedList... - roomSummaryEntity.isHiddenFromUser = roomSummaryEntity.versioningState == VersioningState.UPGRADED_ROOM_JOINED - || roomAccountDataDataSource.getAccountDataEvent(roomId, RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM) != null + roomSummaryEntity.isHiddenFromUser = roomSummaryEntity.versioningState == VersioningState.UPGRADED_ROOM_JOINED || + roomAccountDataDataSource.getAccountDataEvent(roomId, RoomAccountDataTypes.EVENT_TYPE_VIRTUAL_ROOM) != null val lastNameEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root val lastTopicEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_TOPIC, stateKey = "")?.root @@ -132,9 +132,9 @@ internal class RoomSummaryUpdater @Inject constructor( roomSummaryEntity.lastActivityTime = lastActivityFromEvent } - roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 + roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0 || // avoid this call if we are sure there are unread events - || !isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId) + !isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId) roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(realm, roomId) roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DefaultTagsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DefaultTagsService.kt index 02acaa0570..131bd40f1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DefaultTagsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tags/DefaultTagsService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.session.room.tags import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.session.room.tags.TagsService internal class DefaultTagsService @AssistedInject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 8cc5d943b7..c0e428ec85 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -475,8 +475,8 @@ internal class DefaultTimeline( val currentChunk = getLiveChunk() val token = if (direction == Timeline.Direction.BACKWARDS) currentChunk?.prevToken else currentChunk?.nextToken if (token == null) { - if (direction == Timeline.Direction.BACKWARDS - || (direction == Timeline.Direction.FORWARDS && currentChunk?.hasBeenALastForwardChunk().orFalse())) { + if (direction == Timeline.Direction.BACKWARDS || + (direction == Timeline.Direction.FORWARDS && currentChunk?.hasBeenALastForwardChunk().orFalse())) { // We are in the case where event exists, but we do not know the token. // Fetch (again) the last event to get a token val lastKnownEventId = if (direction == Timeline.Direction.FORWARDS) { @@ -583,8 +583,8 @@ internal class DefaultTimeline( val transactionId = timelineEvent.root.unsignedData?.transactionId uiEchoManager.onSyncedEvent(transactionId) - if (timelineEvent.isEncrypted() - && timelineEvent.root.mxDecryptionResult == null) { + if (timelineEvent.isEncrypted() && + timelineEvent.root.mxDecryptionResult == null) { timelineEvent.root.eventId?.also { eventDecryptor.requestDecryption(TimelineEventDecryptor.DecryptionRequest(timelineEvent.root, timelineID)) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt index eb4900553b..64b1a4ff1d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LiveTimelineEvent.kt @@ -40,8 +40,8 @@ internal class LiveTimelineEvent(private val monarchy: Monarchy, private val coroutineScope: CoroutineScope, private val timelineEventMapper: TimelineEventMapper, private val roomId: String, - private val eventId: String) - : MediatorLiveData>() { + private val eventId: String) : + MediatorLiveData>() { init { buildAndObserveQuery() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt index a7cba2fe99..dbcc37a918 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt @@ -238,8 +238,8 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri it.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = false) } val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId) - val shouldUpdateSummary = roomSummaryEntity.latestPreviewableEvent == null - || (chunksToDelete.isNotEmpty() && currentChunk.isLastForward && direction == PaginationDirection.FORWARDS) + val shouldUpdateSummary = roomSummaryEntity.latestPreviewableEvent == null || + (chunksToDelete.isNotEmpty() && currentChunk.isLastForward && direction == PaginationDirection.FORWARDS) if (shouldUpdateSummary) { roomSummaryEntity.latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tombstone/RoomTombstoneEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tombstone/RoomTombstoneEventProcessor.kt index 8022d98975..2b404775f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tombstone/RoomTombstoneEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/tombstone/RoomTombstoneEventProcessor.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.tombstone +import io.realm.Realm 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.toModel @@ -25,7 +26,6 @@ import org.matrix.android.sdk.internal.database.model.EventInsertType import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor -import io.realm.Realm import javax.inject.Inject internal class RoomTombstoneEventProcessor @Inject constructor() : EventInsertLiveProcessor { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/DefaultUploadsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/DefaultUploadsService.kt index 6d841644dc..99cf36faec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/DefaultUploadsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/DefaultUploadsService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.session.room.uploads import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.room.uploads.GetUploadsResult import org.matrix.android.sdk.api.session.room.uploads.UploadsService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt index 9c25eccb3a..19f34746ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignOutTask.kt @@ -50,9 +50,9 @@ internal class DefaultSignOutTask @Inject constructor( } } catch (throwable: Throwable) { // Maybe due to https://github.com/matrix-org/synapse/issues/5756 - if (throwable is Failure.ServerError - && throwable.httpCode == HttpURLConnection.HTTP_UNAUTHORIZED /* 401 */ - && throwable.error.code == MatrixError.M_UNKNOWN_TOKEN) { + if (throwable is Failure.ServerError && + throwable.httpCode == HttpURLConnection.HTTP_UNAUTHORIZED && /* 401 */ + throwable.error.code == MatrixError.M_UNKNOWN_TOKEN) { // Also throwable.error.isSoftLogout should be true // Ignore Timber.w("Ignore error due to https://github.com/matrix-org/synapse/issues/5755") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt index 5cbaaa45c4..c45d4420ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt @@ -76,9 +76,9 @@ internal class DefaultPeekSpaceTask @Inject constructor( if (depth >= maxDepth) return emptyList() val childRoomsIds = stateEvents .filter { - it.type == EventType.STATE_SPACE_CHILD && !it.stateKey.isNullOrEmpty() + it.type == EventType.STATE_SPACE_CHILD && !it.stateKey.isNullOrEmpty() && // Children where via is not present are ignored. - && it.content?.toModel()?.via != null + it.content?.toModel()?.via != null } .map { it.stateKey to it.content?.toModel() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt index 44d879f05d..a2ffd8221a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt @@ -28,6 +28,7 @@ data class SpacePeekSummary( interface ISpaceChild { val id: String val roomPeekResult: PeekResult + // val default: Boolean? val order: String? } @@ -52,5 +53,5 @@ sealed class SpacePeekResult { data class FailedToResolve(val spaceId: String, val roomPeekResult: PeekResult) : SpacePeekError() data class NotSpaceType(val spaceId: String) : SpacePeekError() - data class Success(val summary: SpacePeekSummary): SpacePeekResult() + data class Success(val summary: SpacePeekSummary) : SpacePeekResult() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt index 411a9c5c06..cec5689a82 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt @@ -21,14 +21,14 @@ 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.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.session.initsync.ProgressReporter -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse -import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse import timber.log.Timber import javax.inject.Inject @@ -42,8 +42,8 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService: // Decrypt event if necessary Timber.i("## CRYPTO | To device event from ${event.senderId} of type:${event.type}") decryptToDeviceEvent(event, null) - if (event.getClearType() == EventType.MESSAGE - && event.getClearContent()?.toModel()?.msgType == "m.bad.encrypted") { + if (event.getClearType() == EventType.MESSAGE && + event.getClearContent()?.toModel()?.msgType == "m.bad.encrypted") { Timber.e("## CRYPTO | handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}") } else { verificationService.onToDeviceEvent(event) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt index 02362bf050..2b054e578f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/GroupSyncHandler.kt @@ -19,14 +19,14 @@ package org.matrix.android.sdk.internal.session.sync import io.realm.Realm import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.InvitedGroupSync import org.matrix.android.sdk.internal.database.model.GroupEntity import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.mapWithProgress -import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.InvitedGroupSync import javax.inject.Inject internal class GroupSyncHandler @Inject constructor() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt index cf67bbd805..bd20ada28b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStatusRepository.kt @@ -63,8 +63,8 @@ internal class FileInitialSyncStatusRepository(directory: File) : InitialSyncSta override fun getStep(): Int { ensureCache() val state = cache?.step ?: InitialSyncStatus.STEP_INIT - return if (state >= InitialSyncStatus.STEP_DOWNLOADED - && System.currentTimeMillis() > (cache?.downloadedDate ?: 0) + INIT_SYNC_FILE_LIFETIME) { + return if (state >= InitialSyncStatus.STEP_DOWNLOADED && + System.currentTimeMillis() > (cache?.downloadedDate ?: 0) + INIT_SYNC_FILE_LIFETIME) { Timber.d("INIT_SYNC downloaded file is outdated, download it again") // The downloaded file is outdated setStep(InitialSyncStatus.STEP_INIT) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt index 7d93e30191..4bc866b36d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt @@ -39,7 +39,7 @@ sealed class InitialSyncStrategy { * Limit to reach to decide to split the init sync response into smaller files * Empiric value: 1 megabytes */ - val minSizeToSplit: Long = 1024 * 1024, + val minSizeToSplit: Long = 1_048_576, // 1024 * 1024 /** * Limit per room to reach to decide to store a join room ephemeral Events into a file * Empiric value: 1 kilobytes diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomFullyReadHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomFullyReadHandler.kt index e8934fdf21..3d0db212c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomFullyReadHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomFullyReadHandler.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.sync +import io.realm.Realm import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.session.room.read.FullyReadContent -import io.realm.Realm import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt index c6ff71cfcf..e8f74bbd48 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt @@ -20,8 +20,8 @@ import com.squareup.moshi.JsonReader import com.squareup.moshi.Moshi import okio.buffer import okio.source +import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral import org.matrix.android.sdk.internal.di.SessionFilesDirectory -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral import org.matrix.android.sdk.internal.util.md5 import timber.log.Timber import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index 830e666c95..52e5b6b58d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -26,6 +26,10 @@ import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.RoomSync +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult @@ -58,10 +62,6 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent -import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral -import org.matrix.android.sdk.internal.session.sync.model.RoomSync -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.session.sync.parsing.RoomSyncAccountDataHandler import org.matrix.android.sdk.internal.util.computeBestChunkSize import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTagHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTagHandler.kt index add5d841d1..8997435be4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTagHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTagHandler.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.session.sync +import io.realm.Realm import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.model.RoomTagEntity -import io.realm.Realm import org.matrix.android.sdk.internal.database.query.getOrCreate import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTypingUsersHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTypingUsersHandler.kt index b7851031ad..1433d89143 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTypingUsersHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomTypingUsersHandler.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.sync +import io.realm.Realm import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker -import io.realm.Realm import javax.inject.Inject internal class RoomTypingUsersHandler @Inject constructor(@UserId private val userId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt index 2616803463..73ec0aa7ef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncAPI.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.sync import okhttp3.ResponseBody +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.network.TimeOutInterceptor -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse import retrofit2.Call import retrofit2.http.GET import retrofit2.http.Header diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index a4468a96c9..8c7401ab47 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -21,6 +21,9 @@ import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.pushrules.PushRuleService import org.matrix.android.sdk.api.pushrules.RuleScope import org.matrix.android.sdk.api.session.initsync.InitSyncStep +import org.matrix.android.sdk.api.session.sync.model.GroupsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId @@ -30,9 +33,6 @@ import org.matrix.android.sdk.internal.session.group.GetGroupDataWorker import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import org.matrix.android.sdk.internal.session.initsync.reportSubtask import org.matrix.android.sdk.internal.session.notification.ProcessEventForPushTask -import org.matrix.android.sdk.internal.session.sync.model.GroupsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.RoomsSyncResponse -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.util.awaitTransaction import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt index 9bb2bfc9b1..cc4ccc2e46 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync internal class SyncResponsePostTreatmentAggregator { // List of RoomId val ephemeralFilesToDelete = mutableListOf() + // Map of roomId to directUserId val directChatsToCheck = mutableMapOf() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index df3d8492c3..621a08a414 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -20,6 +20,8 @@ import okhttp3.ResponseBody import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.initsync.SyncStatusService +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.GlobalErrorReceiver @@ -30,7 +32,6 @@ import org.matrix.android.sdk.internal.session.filter.FilterRepository import org.matrix.android.sdk.internal.session.homeserver.GetHomeServerCapabilitiesTask import org.matrix.android.sdk.internal.session.initsync.DefaultSyncStatusService import org.matrix.android.sdk.internal.session.initsync.reportSubtask -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.internal.session.sync.parsing.InitialSyncResponseParser import org.matrix.android.sdk.internal.session.user.UserStore import org.matrix.android.sdk.internal.task.Task @@ -44,7 +45,7 @@ import javax.inject.Inject private val loggerTag = LoggerTag("SyncTask", LoggerTag.SYNC) -internal interface SyncTask : Task { +internal interface SyncTask : Task { data class Params( val timeout: Long, @@ -72,13 +73,13 @@ internal class DefaultSyncTask @Inject constructor( private val workingDir = File(fileDirectory, "is") private val initialSyncStatusRepository: InitialSyncStatusRepository = FileInitialSyncStatusRepository(workingDir) - override suspend fun execute(params: SyncTask.Params) { - syncTaskSequencer.post { + override suspend fun execute(params: SyncTask.Params): SyncResponse { + return syncTaskSequencer.post { doSync(params) } } - private suspend fun doSync(params: SyncTask.Params) { + private suspend fun doSync(params: SyncTask.Params): SyncResponse { Timber.tag(loggerTag.value).d("Sync task started on Thread: ${Thread.currentThread().name}") val requestParams = HashMap() @@ -103,6 +104,7 @@ internal class DefaultSyncTask @Inject constructor( val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT) + var syncResponseToReturn: SyncResponse? = null if (isInitialSync) { Timber.tag(loggerTag.value).d("INIT_SYNC with filter: ${requestParams["filter"]}") val initSyncStrategy = initialSyncStrategy @@ -111,7 +113,7 @@ internal class DefaultSyncTask @Inject constructor( roomSyncEphemeralTemporaryStore.reset() workingDir.mkdirs() val file = downloadInitSyncResponse(requestParams) - reportSubtask(defaultSyncStatusService, InitSyncStep.ImportingAccount, 1, 0.7F) { + syncResponseToReturn = reportSubtask(defaultSyncStatusService, InitSyncStep.ImportingAccount, 1, 0.7F) { handleSyncFile(file, initSyncStrategy) } // Delete all files @@ -125,10 +127,10 @@ internal class DefaultSyncTask @Inject constructor( ) } } - logDuration("INIT_SYNC Database insertion", loggerTag) { syncResponseHandler.handleResponse(syncResponse, token, defaultSyncStatusService) } + syncResponseToReturn = syncResponse } } defaultSyncStatusService.endAll() @@ -155,10 +157,13 @@ internal class DefaultSyncTask @Inject constructor( toDevice = nbToDevice )) syncResponseHandler.handleResponse(syncResponse, token, null) + syncResponseToReturn = syncResponse Timber.tag(loggerTag.value).d("Incremental sync done") defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncDone) } Timber.tag(loggerTag.value).d("Sync task finished on Thread: ${Thread.currentThread().name}") + // Should throw if null as it's a mandatory value. + return syncResponseToReturn!! } private suspend fun downloadInitSyncResponse(requestParams: Map): File { @@ -215,8 +220,8 @@ internal class DefaultSyncTask @Inject constructor( } } - private suspend fun handleSyncFile(workingFile: File, initSyncStrategy: InitialSyncStrategy.Optimized) { - logDuration("INIT_SYNC handleSyncFile()", loggerTag) { + private suspend fun handleSyncFile(workingFile: File, initSyncStrategy: InitialSyncStrategy.Optimized): SyncResponse { + return logDuration("INIT_SYNC handleSyncFile()", loggerTag) { val syncResponse = logDuration("INIT_SYNC Read file and parse", loggerTag) { syncResponseParser.parse(initSyncStrategy, workingFile) } @@ -230,6 +235,7 @@ internal class DefaultSyncTask @Inject constructor( syncResponseHandler.handleResponse(syncResponse, null, defaultSyncStatusService) } initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS) + syncResponse } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTokenStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTokenStore.kt index cf061586b7..35e561a106 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTokenStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTokenStore.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.sync import com.zhuinden.monarchy.Monarchy +import io.realm.Realm import org.matrix.android.sdk.internal.database.model.SyncEntity import org.matrix.android.sdk.internal.di.SessionDatabase -import io.realm.Realm import javax.inject.Inject internal class SyncTokenStore @Inject constructor(@SessionDatabase private val monarchy: Monarchy) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt index 110e77813d..a9926c70aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt @@ -29,6 +29,8 @@ import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync +import org.matrix.android.sdk.api.session.sync.model.UserAccountDataSync import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.mapper.PushRulesMapper import org.matrix.android.sdk.internal.database.mapper.asDomain @@ -48,11 +50,9 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.RoomAvatarResolver import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper -import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.internal.session.sync.model.accountdata.BreadcrumbsContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.DirectMessagesContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUsersContent -import org.matrix.android.sdk.internal.session.sync.model.accountdata.UserAccountDataSync import org.matrix.android.sdk.internal.session.sync.model.accountdata.toMutable import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt index b3a6cafb7d..e1150f2c47 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt @@ -21,25 +21,28 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer import com.squareup.moshi.JsonEncodingException import kotlinx.coroutines.CancellationException -import org.matrix.android.sdk.api.failure.Failure -import org.matrix.android.sdk.api.failure.isTokenError -import org.matrix.android.sdk.api.session.sync.SyncState -import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker -import org.matrix.android.sdk.internal.session.sync.SyncTask -import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver -import org.matrix.android.sdk.internal.util.Debouncer -import org.matrix.android.sdk.internal.util.createUIHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.isTokenError import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.call.MxCall +import org.matrix.android.sdk.api.session.sync.SyncState +import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker import org.matrix.android.sdk.internal.session.call.ActiveCallHandler import org.matrix.android.sdk.internal.session.sync.SyncPresence +import org.matrix.android.sdk.internal.session.sync.SyncTask +import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver +import org.matrix.android.sdk.internal.util.Debouncer +import org.matrix.android.sdk.internal.util.createUIHandler import timber.log.Timber import java.net.SocketTimeoutException import java.util.Timer @@ -75,6 +78,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, } } + private val _syncFlow = MutableSharedFlow() + init { updateStateTo(SyncState.Idle) } @@ -118,6 +123,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, return liveState } + fun syncFlow(): SharedFlow = _syncFlow + override fun onConnectivityChanged() { retryNoNetworkTask?.cancel() synchronized(lock) { @@ -195,7 +202,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, private suspend fun doSync(params: SyncTask.Params) { try { - syncTask.execute(params) + val syncResponse = syncTask.execute(params) + _syncFlow.emit(syncResponse) } catch (failure: Throwable) { if (failure is Failure.NetworkConnection) { canReachServer = false diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt index 940ea219fb..012470a076 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt @@ -21,10 +21,10 @@ import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import com.squareup.moshi.ToJson +import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral +import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore -import org.matrix.android.sdk.internal.session.sync.model.LazyRoomSyncEphemeral -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncEphemeral import timber.log.Timber internal class DefaultLazyRoomSyncEphemeralJsonAdapter { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt index 0b44887aed..f00cce2d5e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt @@ -19,9 +19,9 @@ package org.matrix.android.sdk.internal.session.sync.parsing import com.squareup.moshi.Moshi import okio.buffer import okio.source +import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt index 8bf9ad5b90..6ca008c5b1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/RoomSyncAccountDataHandler.kt @@ -20,6 +20,7 @@ import io.realm.Realm import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent +import org.matrix.android.sdk.api.session.sync.model.RoomSyncAccountData import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntity @@ -29,7 +30,6 @@ import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.session.room.read.FullyReadContent import org.matrix.android.sdk.internal.session.sync.RoomFullyReadHandler import org.matrix.android.sdk.internal.session.sync.RoomTagHandler -import org.matrix.android.sdk.internal.session.sync.model.RoomSyncAccountData import javax.inject.Inject internal class RoomSyncAccountDataHandler @Inject constructor(private val roomTagHandler: RoomTagHandler, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt index 2c7dc92ddd..d40fd8d076 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt @@ -30,8 +30,8 @@ import org.matrix.android.sdk.internal.session.identity.IdentityAuthAPI import org.matrix.android.sdk.internal.session.identity.IdentityRegisterTask import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask import org.matrix.android.sdk.internal.session.sync.model.accountdata.AcceptedTermsContent -import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask +import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.util.ensureTrailingSlash import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsModule.kt index b7cd7a4a97..d7b6f68add 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsModule.kt @@ -20,11 +20,11 @@ import dagger.Binds import dagger.Lazy import dagger.Module import dagger.Provides +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.session.SessionScope -import okhttp3.OkHttpClient @Module internal abstract class TermsModule { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt index 13829c400a..fdd5524fc2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/thirdparty/DefaultThirdPartyService.kt @@ -22,8 +22,8 @@ import org.matrix.android.sdk.api.session.thirdparty.model.ThirdPartyUser import javax.inject.Inject internal class DefaultThirdPartyService @Inject constructor(private val getThirdPartyProtocolTask: GetThirdPartyProtocolsTask, - private val getThirdPartyUserTask: GetThirdPartyUserTask) - : ThirdPartyService { + private val getThirdPartyUserTask: GetThirdPartyUserTask) : + ThirdPartyService { override suspend fun getThirdPartyProtocols(): Map { return getThirdPartyProtocolTask.execute(Unit) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt index ff1750ce8e..e5c338d511 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt @@ -19,13 +19,13 @@ package org.matrix.android.sdk.internal.session.user.accountdata import androidx.lifecycle.LiveData import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.events.model.Content +import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.internal.session.sync.UserAccountDataSyncHandler -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent -import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataDataSource +import org.matrix.android.sdk.internal.session.sync.UserAccountDataSyncHandler import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.util.awaitCallback diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DirectChatsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DirectChatsHelper.kt index 3703057643..c7b125b5d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DirectChatsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DirectChatsHelper.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.user.accountdata +import io.realm.Realm +import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.getDirectRooms import org.matrix.android.sdk.internal.di.SessionDatabase -import io.realm.Realm -import io.realm.RealmConfiguration import org.matrix.android.sdk.internal.session.sync.model.accountdata.DirectMessagesContent import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/SaveBreadcrumbsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/SaveBreadcrumbsTask.kt index d6c95d6b52..22af56a169 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/SaveBreadcrumbsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/SaveBreadcrumbsTask.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.user.accountdata import com.zhuinden.monarchy.Monarchy +import io.realm.RealmList import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.internal.database.model.BreadcrumbsEntity import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity @@ -25,7 +26,6 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction -import io.realm.RealmList import javax.inject.Inject /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 1a588d2245..88db381852 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.session.user.accountdata +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.integrationmanager.AllowedWidgetsContent import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationProvisioningContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.AcceptedTermsContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.BreadcrumbsContent import org.matrix.android.sdk.internal.session.sync.model.accountdata.IdentityServerContent -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt index ba7a2be2a5..07f7c7cb86 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt @@ -29,8 +29,8 @@ import java.util.HashMap import javax.inject.Inject internal class DefaultWidgetPostAPIMediator @Inject constructor(private val moshi: Moshi, - private val widgetPostMessageAPIProvider: WidgetPostMessageAPIProvider) - : WidgetPostAPIMediator { + private val widgetPostMessageAPIProvider: WidgetPostMessageAPIProvider) : + WidgetPostAPIMediator { private val jsonAdapter = moshi.adapter(JSON_DICT_PARAMETERIZED_TYPE) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt index dfe4b6b810..89e827aea0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetService.kt @@ -28,8 +28,8 @@ import javax.inject.Provider internal class DefaultWidgetService @Inject constructor(private val widgetManager: WidgetManager, private val widgetURLFormatter: WidgetURLFormatter, - private val widgetPostAPIMediator: Provider) - : WidgetService { + private val widgetPostAPIMediator: Provider) : + WidgetService { override fun getWidgetURLFormatter(): WidgetURLFormatter { return widgetURLFormatter diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt index f7664bf3c2..5879b62446 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetURLFormatter.kt @@ -18,12 +18,12 @@ package org.matrix.android.sdk.internal.session.widgets import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter import org.matrix.android.sdk.api.util.appendParamToUrl import org.matrix.android.sdk.api.util.appendParamsToUrl -import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt index e0f43a11c5..9f5f91d917 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt @@ -23,6 +23,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.Content @@ -35,7 +36,6 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.api.session.SessionLifecycleObserver import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource @@ -51,9 +51,9 @@ internal class WidgetManager @Inject constructor(private val integrationManager: private val stateEventDataSource: StateEventDataSource, private val createWidgetTask: CreateWidgetTask, private val widgetFactory: WidgetFactory, - @UserId private val userId: String) + @UserId private val userId: String) : - : IntegrationManagerService.Listener, SessionLifecycleObserver { + IntegrationManagerService.Listener, SessionLifecycleObserver { private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner) @@ -155,8 +155,8 @@ internal class WidgetManager @Inject constructor(private val integrationManager: return extractWidgetSequence(widgetFactory) .filter { val widgetType = it.widgetContent.type ?: return@filter false - (widgetTypes == null || widgetTypes.contains(widgetType)) - && (excludedTypes == null || !excludedTypes.contains(widgetType)) + (widgetTypes == null || widgetTypes.contains(widgetType)) && + (excludedTypes == null || !excludedTypes.contains(widgetType)) } .toList() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPIProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPIProvider.kt index 7f79f44767..48c8fcdb03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPIProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPIProvider.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session.widgets import dagger.Lazy +import okhttp3.OkHttpClient import org.matrix.android.sdk.internal.di.Unauthenticated import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.session.SessionScope -import okhttp3.OkHttpClient import javax.inject.Inject @SessionScope diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt index 6f423b38a0..21fbb77667 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/UserAccountWidgets.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.session.widgets.helper +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.widgets.model.Widget +import org.matrix.android.sdk.api.util.JsonDict internal fun UserAccountDataEvent.extractWidgetSequence(widgetFactory: WidgetFactory): Sequence { return content.asSequence() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt index a469a9fe97..a5e74a8af0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/helper/WidgetFactory.kt @@ -20,11 +20,14 @@ import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.sender.SenderInfo +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.session.widgets.model.WidgetContent import org.matrix.android.sdk.api.session.widgets.model.WidgetType +import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.database.RealmSessionProvider import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.user.UserDataSource import java.net.URLEncoder @@ -32,6 +35,7 @@ import javax.inject.Inject internal class WidgetFactory @Inject constructor(private val userDataSource: UserDataSource, private val realmSessionProvider: RealmSessionProvider, + private val displayNameResolver: DisplayNameResolver, private val urlResolver: ContentUrlResolver, @UserId private val userId: String) { @@ -68,13 +72,13 @@ internal class WidgetFactory @Inject constructor(private val userDataSource: Use // Ref: https://github.com/matrix-org/matrix-widget-api/blob/master/src/templating/url-template.ts#L29-L33 fun computeURL(widget: Widget, isLightTheme: Boolean): String? { var computedUrl = widget.widgetContent.url ?: return null - val myUser = userDataSource.getUser(userId) + val myUser = userDataSource.getUser(userId) ?: User(userId) val keyValue = widget.widgetContent.data.mapKeys { "\$${it.key}" }.toMutableMap() keyValue[WIDGET_PATTERN_MATRIX_USER_ID] = userId - keyValue[WIDGET_PATTERN_MATRIX_DISPLAY_NAME] = myUser?.getBestName() ?: userId - keyValue[WIDGET_PATTERN_MATRIX_AVATAR_URL] = urlResolver.resolveFullSize(myUser?.avatarUrl) ?: "" + keyValue[WIDGET_PATTERN_MATRIX_DISPLAY_NAME] = displayNameResolver.getBestName(myUser.toMatrixItem()) + keyValue[WIDGET_PATTERN_MATRIX_AVATAR_URL] = urlResolver.resolveFullSize(myUser.avatarUrl) ?: "" keyValue[WIDGET_PATTERN_MATRIX_WIDGET_ID] = widget.widgetId keyValue[WIDGET_PATTERN_MATRIX_ROOM_ID] = widget.event.roomId ?: "" keyValue[WIDGET_PATTERN_THEME] = getTheme(isLightTheme) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/token/GetScalarTokenTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/token/GetScalarTokenTask.kt index 78a40d1977..17797cad52 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/token/GetScalarTokenTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/token/GetScalarTokenTask.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.internal.session.widgets.token import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError +import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask -import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure import org.matrix.android.sdk.internal.session.widgets.WidgetsAPI import org.matrix.android.sdk.internal.session.widgets.WidgetsAPIProvider import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineToCallback.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineToCallback.kt index ca4b092e07..de6981ec03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineToCallback.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineToCallback.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.task -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.util.Cancelable -import org.matrix.android.sdk.internal.extensions.foldToCallback -import org.matrix.android.sdk.internal.util.toCancelable import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.util.Cancelable +import org.matrix.android.sdk.internal.extensions.foldToCallback +import org.matrix.android.sdk.internal.util.toCancelable import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/Task.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/Task.kt index a5d031e02a..01066a6f7c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/Task.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/Task.kt @@ -25,7 +25,7 @@ internal interface Task { suspend fun execute(params: PARAMS): RESULT - suspend fun executeRetry(params: PARAMS, remainingRetry: Int) : RESULT { + suspend fun executeRetry(params: PARAMS, remainingRetry: Int): RESULT { return try { execute(params) } catch (failure: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/TaskExecutor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/TaskExecutor.kt index 4da16eff22..86848d1018 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/TaskExecutor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/TaskExecutor.kt @@ -16,16 +16,16 @@ package org.matrix.android.sdk.internal.task -import org.matrix.android.sdk.api.util.Cancelable -import org.matrix.android.sdk.internal.di.MatrixScope -import org.matrix.android.sdk.internal.extensions.foldToCallback -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import org.matrix.android.sdk.internal.util.toCancelable import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.util.Cancelable +import org.matrix.android.sdk.internal.di.MatrixScope +import org.matrix.android.sdk.internal.extensions.foldToCallback +import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +import org.matrix.android.sdk.internal.util.toCancelable import timber.log.Timber import javax.inject.Inject import kotlin.coroutines.EmptyCoroutineContext diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CancelableCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CancelableCoroutine.kt index 860cf66c78..f398ee25d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CancelableCoroutine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CancelableCoroutine.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.util -import org.matrix.android.sdk.api.util.Cancelable import kotlinx.coroutines.Job +import org.matrix.android.sdk.api.util.Cancelable internal fun Job.toCancelable(): Cancelable { return CancelableCoroutine(this) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt index 7b45bab365..a34b91a70b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.util import androidx.annotation.VisibleForTesting -import org.matrix.android.sdk.internal.di.MoshiProvider import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber import java.util.TreeSet diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt index aa0b92aa45..8a6ec18986 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt @@ -78,7 +78,7 @@ internal val spaceChars = "[\u00A0\u2000-\u200B\u2800\u3000]".toRegex() /** * Strip all the UTF-8 chars which are actually spaces */ -internal fun String.replaceSpaceChars() = replace(spaceChars, "") +internal fun String.replaceSpaceChars(replacement: String = "") = replace(spaceChars, replacement) // String.capitalize is now deprecated internal fun String.safeCapitalize(): String { @@ -90,3 +90,5 @@ internal fun String.safeCapitalize(): String { } } } + +internal fun String.removeInvalidRoomNameChars() = "[^a-z0-9._%#@=+-]".toRegex().replace(this, "") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/system/DefaultBuildVersionSdkIntProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/system/DefaultBuildVersionSdkIntProvider.kt index d9f0064f38..2d5e4b944a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/system/DefaultBuildVersionSdkIntProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/system/DefaultBuildVersionSdkIntProvider.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.util.system import android.os.Build import javax.inject.Inject -internal class DefaultBuildVersionSdkIntProvider @Inject constructor() - : BuildVersionSdkIntProvider { +internal class DefaultBuildVersionSdkIntProvider @Inject constructor() : + BuildVersionSdkIntProvider { override fun get() = Build.VERSION.SDK_INT } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt index f11e87e1e7..82ff9a321f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.wellknown import android.util.MalformedJsonException import dagger.Lazy +import okhttp3.OkHttpClient import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.data.WellKnown import org.matrix.android.sdk.api.auth.wellknown.WellknownResult @@ -31,7 +32,6 @@ import org.matrix.android.sdk.internal.session.homeserver.CapabilitiesAPI import org.matrix.android.sdk.internal.session.identity.IdentityAuthAPI import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.isValidUrl -import okhttp3.OkHttpClient import java.io.EOFException import javax.inject.Inject import javax.net.ssl.HttpsURLConnection diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/AlwaysSuccessfulWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/AlwaysSuccessfulWorker.kt index 3506a76f75..856d3debcf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/AlwaysSuccessfulWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/AlwaysSuccessfulWorker.kt @@ -19,8 +19,8 @@ import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters -internal class AlwaysSuccessfulWorker(context: Context, params: WorkerParameters) - : Worker(context, params) { +internal class AlwaysSuccessfulWorker(context: Context, params: WorkerParameters) : + Worker(context, params) { override fun doWork(): Result { return Result.success() diff --git a/matrix-sdk-android/src/release/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/release/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt index f46e2ca35b..47f6869479 100644 --- a/matrix-sdk-android/src/release/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt +++ b/matrix-sdk-android/src/release/java/org/matrix/android/sdk/internal/network/interceptors/CurlLoggingInterceptor.kt @@ -26,8 +26,8 @@ import javax.inject.Inject * No op interceptor */ @MatrixScope -internal class CurlLoggingInterceptor @Inject constructor() - : Interceptor { +internal class CurlLoggingInterceptor @Inject constructor() : + Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/MatrixTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/MatrixTest.kt index f6a7f525db..84f09eb184 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/MatrixTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/MatrixTest.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk -import org.matrix.android.sdk.test.shared.createTimberTestRule import org.junit.Rule +import org.matrix.android.sdk.test.shared.createTimberTestRule interface MatrixTest { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/auth/data/VersionsKtTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/auth/data/VersionsKtTest.kt index c413d9ccae..96655b849d 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/auth/data/VersionsKtTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/auth/data/VersionsKtTest.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.api.auth.data -import org.matrix.android.sdk.internal.auth.version.Versions -import org.matrix.android.sdk.internal.auth.version.isSupportedBySdk import org.amshove.kluent.shouldBe import org.junit.Test +import org.matrix.android.sdk.internal.auth.version.Versions +import org.matrix.android.sdk.internal.auth.version.isSupportedBySdk class VersionsKtTest { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRuleActionsTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRuleActionsTest.kt index b734444990..9bfdea5414 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRuleActionsTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRuleActionsTest.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.api.pushrules -import org.matrix.android.sdk.MatrixTest -import org.matrix.android.sdk.api.pushrules.rest.PushRule -import org.matrix.android.sdk.internal.di.MoshiProvider import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Test +import org.matrix.android.sdk.MatrixTest +import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.internal.di.MoshiProvider -class PushRuleActionsTest: MatrixTest { +class PushRuleActionsTest : MatrixTest { @Test fun test_action_parsing() { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58Test.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58Test.kt index 2f01a43a67..a93883a344 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58Test.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58Test.kt @@ -16,15 +16,15 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.util -import org.matrix.android.sdk.MatrixTest import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.FixMethodOrder import org.junit.Test import org.junit.runners.MethodSorters +import org.matrix.android.sdk.MatrixTest @FixMethodOrder(MethodSorters.JVM) -class Base58Test: MatrixTest { +class Base58Test : MatrixTest { @Test fun encode() { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt index 64ffe52acd..4e4548b197 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt @@ -16,14 +16,14 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.util -import org.matrix.android.sdk.MatrixTest import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test +import org.matrix.android.sdk.MatrixTest -class RecoveryKeyTest: MatrixTest { +class RecoveryKeyTest : MatrixTest { private val curve25519Key = byteArrayOf( 0x77.toByte(), 0x07.toByte(), 0x6D.toByte(), 0x0A.toByte(), 0x73.toByte(), 0x18.toByte(), 0xA5.toByte(), 0x7D.toByte(), diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt index 0bcc7983c5..b50d0581b0 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.store.db -import org.matrix.android.sdk.MatrixTest -import org.matrix.android.sdk.internal.util.md5 import org.junit.Assert.assertEquals import org.junit.Test +import org.matrix.android.sdk.MatrixTest +import org.matrix.android.sdk.internal.util.md5 -class HelperTest: MatrixTest { +class HelperTest : MatrixTest { @Test fun testHash_ok() { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/BinaryStringTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/BinaryStringTest.kt index b04834f9f4..5a82052d1a 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/BinaryStringTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/BinaryStringTest.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode -import org.matrix.android.sdk.MatrixTest import org.amshove.kluent.shouldBeEqualTo import org.junit.FixMethodOrder import org.junit.Test import org.junit.runners.MethodSorters +import org.matrix.android.sdk.MatrixTest @FixMethodOrder(MethodSorters.JVM) class BinaryStringTest : MatrixTest { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt index 3572a1a546..0abca8bee3 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/task/CoroutineSequencersTest.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.task -import org.matrix.android.sdk.MatrixTest import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.delay @@ -25,9 +24,10 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test +import org.matrix.android.sdk.MatrixTest import java.util.concurrent.Executors -class CoroutineSequencersTest: MatrixTest { +class CoroutineSequencersTest : MatrixTest { private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 4b0dd1f0a3..8f8625fe1c 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -141,8 +141,6 @@ android\.app\.AlertDialog androidx\.appcompat\.app\.AlertDialog===4 ### Put the operator at the beginning of next line -&&$ -\|\|$ ==$ ### Use JsonUtils.getBasicGson() diff --git a/vector/build.gradle b/vector/build.gradle index 903798ce55..b3cf745584 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -14,7 +14,7 @@ kapt { // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 3 -ext.versionPatch = 1 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' @@ -361,7 +361,7 @@ dependencies { implementation 'com.facebook.stetho:stetho:1.6.0' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.33' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.34' // rx implementation libs.rx.rxKotlin @@ -412,7 +412,7 @@ dependencies { implementation 'com.nulab-inc:zxcvbn:1.5.2' // To convert voice message on old platforms - implementation 'com.arthenica:ffmpeg-kit-audio:4.4.LTS' + implementation 'com.arthenica:ffmpeg-kit-audio:4.5.LTS' // Alerter implementation 'com.tapadoo.android:alerter:7.0.1' diff --git a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt index d247d88caa..823ce83015 100644 --- a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt +++ b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt @@ -129,7 +129,7 @@ fun activityIdlingResource(activityClass: Class<*>): IdlingResource { private var callback: IdlingResource.ResourceCallback? = null var hasResumed = false - private var currentActivity : Activity? = null + private var currentActivity: Activity? = null val uniqTS = System.currentTimeMillis() override fun getName() = "activityIdlingResource_${activityClass.name}_$uniqTS" diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt index 571bcf474c..982a421425 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt @@ -44,14 +44,14 @@ import org.junit.runner.RunWith import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.auth.UserPasswordAuth +import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.auth.UserPasswordAuth -import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/vector/src/androidTest/java/im/vector/app/espresso/tools/EspressoPreference.kt b/vector/src/androidTest/java/im/vector/app/espresso/tools/EspressoPreference.kt index bf60ad681f..178b9fb9f6 100644 --- a/vector/src/androidTest/java/im/vector/app/espresso/tools/EspressoPreference.kt +++ b/vector/src/androidTest/java/im/vector/app/espresso/tools/EspressoPreference.kt @@ -30,9 +30,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withClassName import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import im.vector.app.R -import org.hamcrest.Matchers.`is` import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.instanceOf +import org.hamcrest.Matchers.`is` fun clickOnPreference(@StringRes textResId: Int) { onView(withId(R.id.recycler_view)) diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt index aef5d3fe49..a9cb5274ed 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -226,7 +226,7 @@ class UiAllScreensSanityTest { // Filter // TODO clickMenu(R.id.search) // Wait for emoji to load, it's async now - sleep(1_000) + sleep(2_000) clickListItem(R.id.emojiRecyclerView, 4) // Test Edit mode diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 4b5228d199..303a3a14ba 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -235,8 +235,8 @@ class DebugMenuActivity : VectorBaseActivity() { private val qrStartForActivityResult = registerStartForActivityResult { activityResult -> if (activityResult.resultCode == Activity.RESULT_OK) { - toast("QrCode: " + QrCodeScannerActivity.getResultText(activityResult.data) - + " is QRCode: " + QrCodeScannerActivity.getResultIsQrCode(activityResult.data)) + toast("QrCode: " + QrCodeScannerActivity.getResultText(activityResult.data) + + " is QRCode: " + QrCodeScannerActivity.getResultIsQrCode(activityResult.data)) // Also update the current QR Code (reverse operation) // renderQrCode(QrCodeScannerActivity.getResultText(data) ?: "") diff --git a/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt b/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt index 408aebb186..a7b74f3b59 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt @@ -23,9 +23,9 @@ import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel -import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import me.gujun.android.span.image import me.gujun.android.span.span +import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation @EpoxyModelClass(layout = im.vector.app.R.layout.item_sas_emoji) abstract class SasEmojiItem : VectorEpoxyModel() { diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt index e46a07f712..27a3f09ddc 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt @@ -27,8 +27,8 @@ import javax.inject.Inject * Test that the application is started on boot */ class TestAutoStartBoot @Inject constructor(private val vectorPreferences: VectorPreferences, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_service_boot_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_service_boot_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { if (vectorPreferences.autoStartOnBoot()) { diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt index abdd696724..3725fc828d 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt @@ -27,8 +27,8 @@ import im.vector.app.features.settings.troubleshoot.TroubleshootTest import javax.inject.Inject class TestBackgroundRestrictions @Inject constructor(private val context: AppCompatActivity, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_bg_restricted_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_bg_restricted_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { context.getSystemService()!!.apply { diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt index 92e713de81..1f822d6060 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt @@ -30,8 +30,8 @@ import javax.inject.Inject * Check that the play services APK is available an up-to-date. If needed provide quick fix to install it. */ class TestPlayServices @Inject constructor(private val context: AppCompatActivity, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_play_services_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_play_services_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { val apiAvailability = GoogleApiAvailability.getInstance() diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt index d429b293b2..e13b648dec 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt @@ -40,8 +40,8 @@ class TestPushFromPushGateway @Inject constructor(private val context: AppCompat private val stringProvider: StringProvider, private val errorFormatter: ErrorFormatter, private val pushersManager: PushersManager, - private val activeSessionHolder: ActiveSessionHolder) - : TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) { + private val activeSessionHolder: ActiveSessionHolder) : + TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) { private var action: Job? = null private var pushReceived: Boolean = false diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt index f400c17d46..966d79c59b 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt @@ -21,13 +21,13 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.work.WorkInfo import androidx.work.WorkManager -import org.matrix.android.sdk.api.session.pushers.PusherState import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.pushers.PushersManager import im.vector.app.core.resources.StringProvider import im.vector.app.features.settings.troubleshoot.TroubleshootTest import im.vector.app.push.fcm.FcmHelper +import org.matrix.android.sdk.api.session.pushers.PusherState import javax.inject.Inject /** @@ -36,8 +36,8 @@ import javax.inject.Inject class TestTokenRegistration @Inject constructor(private val context: AppCompatActivity, private val stringProvider: StringProvider, private val pushersManager: PushersManager, - private val activeSessionHolder: ActiveSessionHolder) - : TroubleshootTest(R.string.settings_troubleshoot_test_token_registration_title) { + private val activeSessionHolder: ActiveSessionHolder) : + TroubleshootTest(R.string.settings_troubleshoot_test_token_registration_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { // Check if we have a registered pusher for this token diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 6c9453a564..7492da37e8 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -83,13 +83,19 @@ android:name="android.max_aspect" android:value="9.9" /> + + + @@ -103,10 +109,13 @@ + + @@ -120,10 +129,13 @@ android:scheme="element" /> + + @@ -143,7 +155,6 @@ android:name=".features.media.VectorAttachmentViewerActivity" android:theme="@style/Theme.Vector.Black.Transparent" tools:ignore="Instantiatable" /> - - @@ -180,7 +190,13 @@ - + + + + @@ -196,8 +212,37 @@ + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + android:supportsPictureInPicture="true" + android:taskAffinity=".features.call.VectorCallActivity" /> @@ -365,7 +386,9 @@ A media button receiver receives and helps translate hardware media playback buttons, such as those found on wired and wireless headsets, into the appropriate callbacks in your app. --> - + @@ -375,9 +398,15 @@ + android:name="androidx.startup.InitializationProvider" + android:authorities="${applicationId}.androidx-startup" + android:exported="false" + tools:node="merge"> + + { when { - throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN -> { + throwable.error.code == MatrixError.M_CONSENT_NOT_GIVEN -> { // Special case for terms and conditions stringProvider.getString(R.string.error_terms_not_accepted) } - throwable.isInvalidPassword() -> { + throwable.isInvalidPassword() -> { stringProvider.getString(R.string.auth_invalid_login_param) } - throwable.error.code == MatrixError.M_USER_IN_USE -> { + throwable.error.code == MatrixError.M_USER_IN_USE -> { stringProvider.getString(R.string.login_signup_error_user_in_use) } - throwable.error.code == MatrixError.M_BAD_JSON -> { + throwable.error.code == MatrixError.M_BAD_JSON -> { stringProvider.getString(R.string.login_error_bad_json) } - throwable.error.code == MatrixError.M_NOT_JSON -> { + throwable.error.code == MatrixError.M_NOT_JSON -> { stringProvider.getString(R.string.login_error_not_json) } - throwable.error.code == MatrixError.M_THREEPID_DENIED -> { + throwable.error.code == MatrixError.M_THREEPID_DENIED -> { stringProvider.getString(R.string.login_error_threepid_denied) } - throwable.error.code == MatrixError.M_LIMIT_EXCEEDED -> { + throwable.error.code == MatrixError.M_LIMIT_EXCEEDED -> { limitExceededError(throwable.error) } - throwable.error.code == MatrixError.M_TOO_LARGE -> { + throwable.error.code == MatrixError.M_TOO_LARGE -> { stringProvider.getString(R.string.error_file_too_big_simple) } - throwable.error.code == MatrixError.M_THREEPID_NOT_FOUND -> { + throwable.error.code == MatrixError.M_THREEPID_NOT_FOUND -> { stringProvider.getString(R.string.login_reset_password_error_not_found) } - throwable.error.code == MatrixError.M_USER_DEACTIVATED -> { + throwable.error.code == MatrixError.M_USER_DEACTIVATED -> { stringProvider.getString(R.string.auth_invalid_login_deactivated_account) } - throwable.error.code == MatrixError.M_THREEPID_IN_USE - && throwable.error.message == "Email is already in use" -> { + throwable.error.code == MatrixError.M_THREEPID_IN_USE && + throwable.error.message == "Email is already in use" -> { stringProvider.getString(R.string.account_email_already_used_error) } - throwable.error.code == MatrixError.M_THREEPID_IN_USE - && throwable.error.message == "MSISDN is already in use" -> { + throwable.error.code == MatrixError.M_THREEPID_IN_USE && + throwable.error.message == "MSISDN is already in use" -> { stringProvider.getString(R.string.account_phone_number_already_used_error) } - throwable.error.code == MatrixError.M_THREEPID_AUTH_FAILED -> { + throwable.error.code == MatrixError.M_THREEPID_AUTH_FAILED -> { stringProvider.getString(R.string.error_threepid_auth_failed) } - else -> { + else -> { throwable.error.message.takeIf { it.isNotEmpty() } ?: throwable.error.code.takeIf { it.isNotEmpty() } } diff --git a/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt index 07a684abef..ee3d79d846 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/BasicExtensions.kt @@ -57,7 +57,7 @@ fun CharSequence.isMsisdn(): Boolean { * - "fi.le.txt".insertBeforeLast("_foo") will return "fi.le_foo.txt" * - null.insertBeforeLast("_foo") will return "_foo" */ -fun String?.insertBeforeLast(insert: String, delimiter: String = ".") : String { +fun String?.insertBeforeLast(insert: String, delimiter: String = "."): String { if (this == null) return insert val idx = lastIndexOf(delimiter) return if (idx == -1) { diff --git a/vector/src/main/java/im/vector/app/core/extensions/EditText.kt b/vector/src/main/java/im/vector/app/core/extensions/EditText.kt index 05b70def3d..0eb9dcdaf9 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/EditText.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/EditText.kt @@ -18,6 +18,7 @@ package im.vector.app.core.extensions import android.text.Editable import android.text.InputType +import android.text.Spanned import android.view.MotionEvent import android.view.View import android.view.inputmethod.EditorInfo @@ -57,3 +58,38 @@ fun EditText.setupAsSearch(@DrawableRes searchIconRes: Int = R.drawable.ic_searc return@OnTouchListener false }) } + +fun EditText.setTextIfDifferent(newText: CharSequence?): Boolean { + if (!isTextDifferent(newText, text)) { + // Previous text is the same. No op + return false + } + setText(newText) + // Since the text changed we move the cursor to the end of the new text. + // This allows us to fill in text programmatically with a different value, + // but if the user is typing and the view is rebound we won't lose their cursor position. + setSelection(newText?.length ?: 0) + return true +} + +private fun isTextDifferent(str1: CharSequence?, str2: CharSequence?): Boolean { + if (str1 === str2) { + return false + } + if (str1 == null || str2 == null) { + return true + } + val length = str1.length + if (length != str2.length) { + return true + } + if (str1 is Spanned) { + return str1 != str2 + } + for (i in 0 until length) { + if (str1[i] != str2[i]) { + return true + } + } + return false +} 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 699247ab6d..215c421291 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 @@ -62,15 +62,15 @@ fun Session.startSyncing(context: Context) { * Tell is the session has unsaved e2e keys in the backup */ fun Session.hasUnsavedKeys(): Boolean { - return cryptoService().inboundGroupSessionsCount(false) > 0 - && cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp + return cryptoService().inboundGroupSessionsCount(false) > 0 && + cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp } fun Session.cannotLogoutSafely(): Boolean { // has some encrypted chat - return hasUnsavedKeys() + return hasUnsavedKeys() || // has local cross signing keys - || (cryptoService().crossSigningService().allPrivateKeysKnown() + (cryptoService().crossSigningService().allPrivateKeysKnown() && // That are not backed up - && !sharedSecretStorageService.isRecoverySetup()) + !sharedSecretStorageService.isRecoverySetup()) } diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt index 0872edeafd..adb655f169 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt @@ -40,8 +40,8 @@ import im.vector.app.features.themes.ThemeUtils * Set a text in the TextView, or set visibility to GONE if the text is null */ fun TextView.setTextOrHide(newText: CharSequence?, hideWhenBlank: Boolean = true, vararg relatedViews: View = emptyArray()) { - if (newText == null - || (newText.isBlank() && hideWhenBlank)) { + if (newText == null || + (newText.isBlank() && hideWhenBlank)) { isVisible = false relatedViews.forEach { it.isVisible = false } } else { diff --git a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt index 48e3a488ed..43ff186e99 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent fun TimelineEvent.canReact(): Boolean { // Only event of type EventType.MESSAGE or EventType.STICKER are supported for the moment - return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) - && root.sendState == SendState.SYNCED - && !root.isRedacted() + return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) && + root.sendState == SendState.SYNCED && + !root.isRedacted() } diff --git a/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt b/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt index 32968c4f80..9675e30042 100644 --- a/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt +++ b/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt @@ -42,8 +42,8 @@ class AvatarPlaceholderModelLoaderFactory(private val context: Context) : ModelL } } -class AvatarPlaceholderModelLoader(private val context: Context) - : ModelLoader { +class AvatarPlaceholderModelLoader(private val context: Context) : + ModelLoader { override fun buildLoadData(model: AvatarPlaceholder, width: Int, height: Int, options: Options): ModelLoader.LoadData? { return ModelLoader.LoadData(ObjectKey(model), AvatarPlaceholderDataFetcher(context, model)) @@ -54,8 +54,8 @@ class AvatarPlaceholderModelLoader(private val context: Context) } } -class AvatarPlaceholderDataFetcher(context: Context, private val data: AvatarPlaceholder) - : DataFetcher { +class AvatarPlaceholderDataFetcher(context: Context, private val data: AvatarPlaceholder) : + DataFetcher { private val avatarRenderer = context.vectorComponent().avatarRenderer() diff --git a/vector/src/main/java/im/vector/app/core/glide/MyAppGlideModule.kt b/vector/src/main/java/im/vector/app/core/glide/MyAppGlideModule.kt index 74c9d4f0f6..59bffd95fd 100644 --- a/vector/src/main/java/im/vector/app/core/glide/MyAppGlideModule.kt +++ b/vector/src/main/java/im/vector/app/core/glide/MyAppGlideModule.kt @@ -19,7 +19,6 @@ package im.vector.app.core.glide import android.content.Context import android.graphics.drawable.Drawable import android.util.Log - import com.bumptech.glide.Glide import com.bumptech.glide.GlideBuilder import com.bumptech.glide.Registry diff --git a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt index 5fae815dfb..7dfee7d981 100644 --- a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt +++ b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt @@ -48,8 +48,8 @@ class VectorGlideModelLoaderFactory(private val context: Context) : ModelLoaderF } } -class VectorGlideModelLoader(private val context: Context) - : ModelLoader { +class VectorGlideModelLoader(private val context: Context) : + ModelLoader { override fun handles(model: ImageContentRenderer.Data): Boolean { // Always handle return true @@ -63,8 +63,8 @@ class VectorGlideModelLoader(private val context: Context) class VectorGlideDataFetcher(context: Context, private val data: ImageContentRenderer.Data, private val width: Int, - private val height: Int) - : DataFetcher { + private val height: Int) : + DataFetcher { private val localFilesHelper = LocalFilesHelper(context) private val activeSessionHolder = context.vectorComponent().activeSessionHolder() diff --git a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt index ee2933f542..e7e91dbfd9 100755 --- a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt @@ -28,8 +28,8 @@ import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.onClick import im.vector.app.databinding.ViewButtonStateBinding -class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : FrameLayout(context, attrs, defStyle) { +class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + FrameLayout(context, attrs, defStyle) { sealed class State { object Button : State() diff --git a/vector/src/main/java/im/vector/app/core/platform/MaxHeightScrollView.kt b/vector/src/main/java/im/vector/app/core/platform/MaxHeightScrollView.kt index 139ccc8c05..8d4c5d8950 100644 --- a/vector/src/main/java/im/vector/app/core/platform/MaxHeightScrollView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/MaxHeightScrollView.kt @@ -24,8 +24,8 @@ import im.vector.app.R private const val DEFAULT_MAX_HEIGHT = 200 -class MaxHeightScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : NestedScrollView(context, attrs, defStyle) { +class MaxHeightScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + NestedScrollView(context, attrs, defStyle) { var maxHeight: Int = 0 set(value) { diff --git a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt index 066bd165a9..7573bf2e8e 100644 --- a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt @@ -21,7 +21,6 @@ import androidx.core.view.isVisible import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.hideKeyboard import im.vector.app.databinding.ActivityBinding - import org.matrix.android.sdk.api.session.Session /** diff --git a/vector/src/main/java/im/vector/app/core/platform/StateView.kt b/vector/src/main/java/im/vector/app/core/platform/StateView.kt index a935c56c51..b3d42dc38f 100755 --- a/vector/src/main/java/im/vector/app/core/platform/StateView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/StateView.kt @@ -26,8 +26,8 @@ import im.vector.app.R import im.vector.app.core.extensions.updateConstraintSet import im.vector.app.databinding.ViewStateBinding -class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : FrameLayout(context, attrs, defStyle) { +class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + FrameLayout(context, attrs, defStyle) { sealed class State { object Content : State() diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorEventViewModel.kt b/vector/src/main/java/im/vector/app/core/platform/VectorEventViewModel.kt index 2d499db531..9ab46557a5 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorEventViewModel.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorEventViewModel.kt @@ -25,5 +25,5 @@ interface VectorSharedAction /** * Parent class to handle navigation events, action events, or other any events */ -open class VectorSharedActionViewModel(private val store: MutableDataSource = PublishDataSource()) - : ViewModel(), MutableDataSource by store +open class VectorSharedActionViewModel(private val store: MutableDataSource = PublishDataSource()) : + ViewModel(), MutableDataSource by store diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt index d6f43beaf7..bca462a92b 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt @@ -27,8 +27,8 @@ import im.vector.app.core.utils.PublishDataSource import io.reactivex.Observable import io.reactivex.Single -abstract class VectorViewModel(initialState: S) - : BaseMvRxViewModel(initialState, false) { +abstract class VectorViewModel(initialState: S) : + BaseMvRxViewModel(initialState, false) { interface Factory { fun create(state: S): BaseMvRxViewModel diff --git a/vector/src/main/java/im/vector/app/core/services/CallService.kt b/vector/src/main/java/im/vector/app/core/services/CallService.kt index cd3845f41b..bda32e528b 100644 --- a/vector/src/main/java/im/vector/app/core/services/CallService.kt +++ b/vector/src/main/java/im/vector/app/core/services/CallService.kt @@ -33,6 +33,7 @@ import im.vector.app.features.call.telecom.CallConnection import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.call.webrtc.getOpponentAsMatrixItem +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.popup.IncomingCallAlert diff --git a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt index e773993b21..bd7a07c640 100644 --- a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt +++ b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt @@ -26,7 +26,6 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetGenericListBinding - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt index f0715e6bba..6e92549809 100644 --- a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt +++ b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt @@ -20,8 +20,8 @@ import com.airbnb.epoxy.TypedEpoxyController /** * Epoxy controller for generic bottom sheet actions */ -abstract class BottomSheetGenericController - : TypedEpoxyController() { +abstract class BottomSheetGenericController : + TypedEpoxyController() { var listener: Listener? = null diff --git a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt index 153cac2ac7..94c1ab6576 100755 --- a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt @@ -25,7 +25,6 @@ import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.di.DefaultSharedPreferences import im.vector.app.databinding.ViewKeysBackupBannerBinding - import timber.log.Timber /** @@ -137,8 +136,8 @@ class KeysBackupBanner @JvmOverloads constructor( } private fun renderSetup(nbOfKeys: Int) { - if (nbOfKeys == 0 - || DefaultSharedPreferences.getInstance(context).getBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)) { + if (nbOfKeys == 0 || + DefaultSharedPreferences.getInstance(context).getBoolean(BANNER_SETUP_DO_NOT_SHOW_AGAIN, false)) { // Do not display the setup banner if there is no keys to backup, or if the user has already closed it isVisible = false } else { diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt index 463d94b288..94809d2981 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt @@ -30,7 +30,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.ViewNotificationAreaBinding import im.vector.app.features.themes.ThemeUtils - import me.gujun.android.span.span import me.saket.bettermovementmethod.BetterLinkMovementMethod import org.matrix.android.sdk.api.failure.MatrixError @@ -50,7 +49,7 @@ class NotificationAreaView @JvmOverloads constructor( var delegate: Delegate? = null private var state: State = State.Initial - private lateinit var views : ViewNotificationAreaBinding + private lateinit var views: ViewNotificationAreaBinding init { setupView() diff --git a/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt b/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt index 2f6c4b45cf..a984707bf7 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt @@ -35,8 +35,8 @@ import im.vector.app.databinding.ViewPasswordStrengthBarBinding class PasswordStrengthBar @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) - : LinearLayout(context, attrs, defStyleAttr) { + defStyleAttr: Int = 0) : + LinearLayout(context, attrs, defStyleAttr) { private val views: ViewPasswordStrengthBarBinding 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 02b351737e..3a79e7e328 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 @@ -37,7 +37,7 @@ class ReadReceiptsView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) { - private val views : ViewReadReceiptsBinding + private val views: ViewReadReceiptsBinding init { setupView() diff --git a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt index c73fa70388..ed3ae00567 100644 --- a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt +++ b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt @@ -40,13 +40,16 @@ fun Context.displayInWebView(url: String) { .show() } -fun Context.showIdentityServerConsentDialog(configuredIdentityServer: String?, consentCallBack: (() -> Unit)) { +fun Context.showIdentityServerConsentDialog(configuredIdentityServer: String?, policyLinkCallback: () -> Unit, consentCallBack: (() -> Unit)) { MaterialAlertDialogBuilder(this) .setTitle(R.string.identity_server_consent_dialog_title) .setMessage(getString(R.string.identity_server_consent_dialog_content, configuredIdentityServer ?: "")) .setPositiveButton(R.string.yes) { _, _ -> consentCallBack.invoke() } + .setNeutralButton(R.string.identity_server_consent_dialog_neutral_policy) { _, _ -> + policyLinkCallback.invoke() + } .setNegativeButton(R.string.no, null) .show() } diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index 9f1497a40a..ba396ed252 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -52,8 +52,7 @@ private var permissionDialogDisplayed = false * So when the user does not grant the permission and check the box do not ask again, this boolean will be false. * Only useful if the first boolean is false */ -fun ComponentActivity.registerForPermissionsResult(lambda: (allGranted: Boolean, deniedPermanently: Boolean) -> Unit) - : ActivityResultLauncher> { +fun ComponentActivity.registerForPermissionsResult(lambda: (allGranted: Boolean, deniedPermanently: Boolean) -> Unit): ActivityResultLauncher> { return registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result -> onPermissionResult(result, lambda) } diff --git a/vector/src/main/java/im/vector/app/core/utils/SnapHelperUtils.kt b/vector/src/main/java/im/vector/app/core/utils/SnapHelperUtils.kt index e039e0bde5..070c953a3f 100644 --- a/vector/src/main/java/im/vector/app/core/utils/SnapHelperUtils.kt +++ b/vector/src/main/java/im/vector/app/core/utils/SnapHelperUtils.kt @@ -59,8 +59,8 @@ class SnapOnScrollListener( } override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { - if (behavior == Behavior.NOTIFY_ON_SCROLL_STATE_IDLE - && newState == RecyclerView.SCROLL_STATE_IDLE) { + if (behavior == Behavior.NOTIFY_ON_SCROLL_STATE_IDLE && + newState == RecyclerView.SCROLL_STATE_IDLE) { maybeNotifySnapPositionChange(recyclerView) } } diff --git a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt index b12c1b7369..966b38828e 100644 --- a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt @@ -48,8 +48,8 @@ import im.vector.app.features.notifications.NotificationUtils */ fun isIgnoringBatteryOptimizations(context: Context): Boolean { // no issue before Android M, battery optimisations did not exist - return Build.VERSION.SDK_INT < Build.VERSION_CODES.M - || context.getSystemService()?.isIgnoringBatteryOptimizations(context.packageName) == true + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || + context.getSystemService()?.isIgnoringBatteryOptimizations(context.packageName) == true } fun isAirplaneModeOn(context: Context): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 583aae260b..e124dbdf6e 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -45,10 +45,10 @@ import im.vector.app.features.signout.soft.SoftLogoutActivity import im.vector.app.features.signout.soft.SoftLogoutActivity2 import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.ui.UiStateRepository -import kotlinx.parcelize.Parcelize import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber import javax.inject.Inject @@ -220,20 +220,20 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity private fun startNextActivityAndFinish(ignoreClearCredentials: Boolean = false) { val intent = when { - args.clearCredentials - && !ignoreClearCredentials - && (!args.isUserLoggedOut || args.isAccountDeactivated) -> { + args.clearCredentials && + !ignoreClearCredentials && + (!args.isUserLoggedOut || args.isAccountDeactivated) -> { // User has explicitly asked to log out or deactivated his account navigator.openLogin(this, null) null } - args.isSoftLogout -> + args.isSoftLogout -> // The homeserver has invalidated the token, with a soft logout getSoftLogoutActivityIntent() - args.isUserLoggedOut -> + args.isUserLoggedOut -> // the homeserver has invalidated the token (password changed, device deleted, other security reasons) SignedOutActivity.newIntent(this) - sessionHolder.hasActiveSession() -> + sessionHolder.hasActiveSession() -> // We have a session. // Check it can be opened if (sessionHolder.getActiveSession().isOpenable) { @@ -242,7 +242,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity // The token is still invalid getSoftLogoutActivityIntent() } - else -> { + else -> { // First start, or no active session navigator.openLogin(this, null) null diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt index eba5dadeda..35644e1843 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt @@ -53,8 +53,8 @@ private const val ANIMATION_DURATION = 250 */ class AttachmentTypeSelectorView(context: Context, inflater: LayoutInflater, - var callback: Callback?) - : PopupWindow(context) { + var callback: Callback?) : + PopupWindow(context) { interface Callback { fun onTypeSelected(type: Type) diff --git a/vector/src/main/java/im/vector/app/features/attachments/ContentAttachmentData.kt b/vector/src/main/java/im/vector/app/features/attachments/ContentAttachmentData.kt index 0502f2b0ad..9805b6f755 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/ContentAttachmentData.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/ContentAttachmentData.kt @@ -27,9 +27,9 @@ private val listOfPreviewableMimeTypes = listOf( fun ContentAttachmentData.isPreviewable(): Boolean { // Preview supports image and video - return (type == ContentAttachmentData.Type.IMAGE - && listOfPreviewableMimeTypes.contains(getSafeMimeType() ?: "")) - || type == ContentAttachmentData.Type.VIDEO + return (type == ContentAttachmentData.Type.IMAGE && + listOfPreviewableMimeTypes.contains(getSafeMimeType() ?: "")) || + type == ContentAttachmentData.Type.VIDEO } data class GroupedContentAttachmentData( diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt index 28d617e613..0a0e700ce9 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewViewModel.kt @@ -20,8 +20,8 @@ package im.vector.app.features.attachments.preview import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel -class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) - : VectorViewModel(initialState) { +class AttachmentsPreviewViewModel(initialState: AttachmentsPreviewViewState) : + VectorViewModel(initialState) { override fun handle(action: AttachmentsPreviewAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/Extensions.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/Extensions.kt index 853f9f8997..672cde977d 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/Extensions.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/Extensions.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.util.MimeTypes.isMimeTypeImage * All images are editable, expect Gif */ fun ContentAttachmentData.isEditable(): Boolean { - return type == ContentAttachmentData.Type.IMAGE - && getSafeMimeType()?.isMimeTypeImage() == true - && getSafeMimeType() != MimeTypes.Gif + return type == ContentAttachmentData.Type.IMAGE && + getSafeMimeType()?.isMimeTypeImage() == true && + getSafeMimeType() != MimeTypes.Gif } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index 3d70615abf..dba2661927 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -26,6 +26,7 @@ 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.extensions.setTextOrHide +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/command/CommandAutocompletePolicy.kt b/vector/src/main/java/im/vector/app/features/autocomplete/command/CommandAutocompletePolicy.kt index 603ec64a7c..08f61be0f8 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/command/CommandAutocompletePolicy.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/command/CommandAutocompletePolicy.kt @@ -37,8 +37,8 @@ class CommandAutocompletePolicy @Inject constructor() : AutocompletePolicy { // Only if text which starts with '/' and without space override fun shouldShowPopup(text: Spannable?, cursorPos: Int): Boolean { - return enabled && text?.startsWith("/") == true - && !text.contains(" ") + return enabled && text?.startsWith("/") == true && + !text.contains(" ") } override fun shouldDismissPopup(text: Spannable?, cursorPos: Int): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index f71dcc0635..42e14efad3 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -55,6 +55,7 @@ import im.vector.app.features.call.dialpad.DialPadFragment import im.vector.app.features.call.utils.EglUtils import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailArgs diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt index 1834c05e41..67aa7bede2 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt @@ -25,9 +25,9 @@ sealed class VectorCallViewActions : VectorViewModelAction { object DeclineCall : VectorCallViewActions() object ToggleMute : VectorCallViewActions() object ToggleVideo : VectorCallViewActions() - object ToggleHoldResume: VectorCallViewActions() + object ToggleHoldResume : VectorCallViewActions() data class ChangeAudioDevice(val device: CallAudioManager.Device) : VectorCallViewActions() - object OpenDialPad: VectorCallViewActions() + object OpenDialPad : VectorCallViewActions() data class SendDtmfDigit(val digit: String) : VectorCallViewActions() data class SwitchCall(val callArgs: CallArgs) : VectorCallViewActions() @@ -36,5 +36,5 @@ sealed class VectorCallViewActions : VectorViewModelAction { object ToggleCamera : VectorCallViewActions() object ToggleHDSD : VectorCallViewActions() object InitiateCallTransfer : VectorCallViewActions() - object TransferCall: VectorCallViewActions() + object TransferCall : VectorCallViewActions() } diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt index 9f19429c00..5a0a2f127c 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt @@ -27,8 +27,8 @@ sealed class VectorCallViewEvents : VectorViewEvents { val available: Set, val current: CallAudioManager.Device ) : VectorCallViewEvents() - object ShowDialPad: VectorCallViewEvents() - object ShowCallTransferScreen: VectorCallViewEvents() + object ShowDialPad : VectorCallViewEvents() + object ShowCallTransferScreen : VectorCallViewEvents() // data class CallAnswered(val content: CallAnswerContent) : VectorCallViewEvents() // data class CallHangup(val content: CallHangupContent) : VectorCallViewEvents() // object CallAccepted : VectorCallViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt b/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt index cfa076f31b..0a63ad6907 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt @@ -51,8 +51,8 @@ class ConferenceEventEmitter(private val context: Context) { } class ConferenceEventObserver(private val context: Context, - private val onBroadcastEvent: (ConferenceEvent) -> Unit) - : LifecycleObserver { + private val onBroadcastEvent: (ConferenceEvent) -> Unit) : + LifecycleObserver { // See https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-android-sdk#listening-for-broadcasted-events private val broadcastReceiver = object : BroadcastReceiver() { diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewActions.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewActions.kt index 830af7de01..7c9b9385f9 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewActions.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewActions.kt @@ -25,5 +25,5 @@ sealed class JitsiCallViewActions : VectorViewModelAction { /** * The ViewModel will either ask the View to finish, or to join another conf. */ - object OnConferenceLeft: JitsiCallViewActions() + object OnConferenceLeft : JitsiCallViewActions() } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewEvents.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewEvents.kt index c8d570a73f..25062ffe15 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewEvents.kt @@ -34,6 +34,6 @@ sealed class JitsiCallViewEvents : VectorViewEvents { ) : JitsiCallViewEvents() object LeaveConference : JitsiCallViewEvents() - object FailJoiningConference: JitsiCallViewEvents() + object FailJoiningConference : JitsiCallViewEvents() object Finish : JitsiCallViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt index 0fc85cb58c..0b86114f6c 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt @@ -104,8 +104,8 @@ class JitsiCallViewModel @AssistedInject constructor( private fun handleSwitchTo(action: JitsiCallViewActions.SwitchTo) = withState { state -> // Check if it is the same conf - if (action.args.roomId != state.roomId - || action.args.widgetId != state.widgetId) { + if (action.args.roomId != state.roomId || + action.args.widgetId != state.widgetId) { if (action.withConfirmation) { // Ask confirmation to switch, but wait a bit for the Activity to quit the PiP mode viewModelScope.launch { diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt index b8b6d83dd1..b691296ba3 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt @@ -22,6 +22,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.ensureProtocol import im.vector.app.core.utils.toBase32String import im.vector.app.features.call.conference.jwt.JitsiJWTFactory +import im.vector.app.features.displayname.getBestName import im.vector.app.features.raw.wellknown.getElementWellknown import im.vector.app.features.settings.VectorLocale import im.vector.app.features.themes.ThemeProvider diff --git a/vector/src/main/java/im/vector/app/features/call/conference/RemoveJitsiWidgetView.kt b/vector/src/main/java/im/vector/app/features/call/conference/RemoveJitsiWidgetView.kt index 391471d2f2..fd7fc31e6d 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/RemoveJitsiWidgetView.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/RemoveJitsiWidgetView.kt @@ -87,10 +87,10 @@ import org.matrix.android.sdk.api.session.room.model.Membership fun render(roomDetailViewState: RoomDetailViewState) { val summary = roomDetailViewState.asyncRoomSummary() - val newState = if (summary?.membership != Membership.JOIN - || roomDetailViewState.isWebRTCCallOptionAvailable() - || !roomDetailViewState.isAllowedToManageWidgets - || roomDetailViewState.jitsiState.widgetId == null) { + val newState = if (summary?.membership != Membership.JOIN || + roomDetailViewState.isWebRTCCallOptionAvailable() || + !roomDetailViewState.isAllowedToManageWidgets || + roomDetailViewState.jitsiState.widgetId == null) { State.Unmount } else if (roomDetailViewState.jitsiState.deleteWidgetInProgress) { State.Progress diff --git a/vector/src/main/java/im/vector/app/features/call/dialpad/CallDialPadBottomSheet.kt b/vector/src/main/java/im/vector/app/features/call/dialpad/CallDialPadBottomSheet.kt index 3472d01c72..8bf2ce47bd 100644 --- a/vector/src/main/java/im/vector/app/features/call/dialpad/CallDialPadBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/call/dialpad/CallDialPadBottomSheet.kt @@ -87,7 +87,7 @@ class CallDialPadBottomSheet : VectorBaseBottomSheetDialogFragment(initialState) { + private val callManager: WebRtcCallManager) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt index 56368b8175..e632d00790 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCall.kt @@ -636,8 +636,8 @@ class WebRtcCall( // We consider a call to be on hold only if *all* the tracks are on hold // (is this the right thing to do?) for (transceiver in peerConnection?.transceivers ?: emptyList()) { - val trackOnHold = transceiver.currentDirection == RtpTransceiver.RtpTransceiverDirection.INACTIVE - || transceiver.currentDirection == RtpTransceiver.RtpTransceiverDirection.RECV_ONLY + val trackOnHold = transceiver.currentDirection == RtpTransceiver.RtpTransceiverDirection.INACTIVE || + transceiver.currentDirection == RtpTransceiver.RtpTransceiverDirection.RECV_ONLY if (!trackOnHold) callOnHold = false } return callOnHold @@ -891,8 +891,8 @@ class WebRtcCall( val polite = !mxCall.isOutgoing // Here we follow the perfect negotiation logic from // https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation - val offerCollision = description.type == SdpType.OFFER - && (makingOffer || peerConnection.signalingState() != PeerConnection.SignalingState.STABLE) + val offerCollision = description.type == SdpType.OFFER && + (makingOffer || peerConnection.signalingState() != PeerConnection.SignalingState.STABLE) ignoreOffer = !polite && offerCollision if (ignoreOffer) { diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 206c5af17a..33ccd08d22 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -28,14 +28,20 @@ enum class Command(val command: String, val parameters: String, @StringRes val d EMOTE("/me", "", R.string.command_description_emote, false), BAN_USER("/ban", " [reason]", R.string.command_description_ban_user, false), UNBAN_USER("/unban", " [reason]", R.string.command_description_unban_user, false), + IGNORE_USER("/ignore", " [reason]", R.string.command_description_ignore_user, false), + UNIGNORE_USER("/unignore", "", R.string.command_description_unignore_user, false), SET_USER_POWER_LEVEL("/op", " []", R.string.command_description_op_user, false), RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user, false), + ROOM_NAME("/roomname", "", R.string.command_description_room_name, false), INVITE("/invite", " [reason]", R.string.command_description_invite_user, false), JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), PART("/part", " [reason]", R.string.command_description_part_room, false), TOPIC("/topic", "", R.string.command_description_topic, false), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user, false), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick, false), + CHANGE_DISPLAY_NAME_FOR_ROOM("/myroomnick", "", R.string.command_description_nick_for_room, false), + ROOM_AVATAR("/roomavatar", "", R.string.command_description_room_avatar, true /* Since user has to know the mxc url */), + CHANGE_AVATAR_FOR_ROOM("/myroomavatar", "", R.string.command_description_avatar_for_room, true /* Since user has to know the mxc url */), MARKDOWN("/markdown", "", R.string.command_description_markdown, false), RAINBOW("/rainbow", "", R.string.command_description_rainbow, false), RAINBOW_EMOTE("/rainbowme", "", R.string.command_description_rainbow_emote, false), @@ -43,11 +49,13 @@ enum class Command(val command: String, val parameters: String, @StringRes val d SPOILER("/spoiler", "", R.string.command_description_spoiler, false), POLL("/poll", "Question | Option 1 | Option 2 ...", R.string.command_description_poll, false), SHRUG("/shrug", "", R.string.command_description_shrug, false), + LENNY("/lenny", "", R.string.command_description_lenny, false), PLAIN("/plain", "", R.string.command_description_plain, false), + WHOIS("/whois", "", R.string.command_description_whois, false), DISCARD_SESSION("/discardsession", "", R.string.command_description_discard_session, false), CONFETTI("/confetti", "", R.string.command_confetti, false), SNOWFALL("/snowfall", "", R.string.command_snow, false), - CREATE_SPACE("/createspace", " *", R.string.command_description_create_space, true), + CREATE_SPACE("/createspace", " *", R.string.command_description_create_space, true), ADD_TO_SPACE("/addToSpace", "spaceId", R.string.command_description_add_to_space, true), JOIN_SPACE("/joinSpace", "spaceId", R.string.command_description_join_space, true), LEAVE_ROOM("/leave", "", R.string.command_description_leave_room, true), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index adba6e4a18..e570033d35 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -20,6 +20,7 @@ import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.isMsisdn import im.vector.app.features.home.room.detail.ChatEffect import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl import org.matrix.android.sdk.api.session.identity.ThreePid import timber.log.Timber @@ -61,7 +62,7 @@ object CommandParser { } return when (val slashCommand = messageParts.first()) { - Command.PLAIN.command -> { + Command.PLAIN.command -> { val text = textMessage.substring(Command.PLAIN.command.length).trim() if (text.isNotEmpty()) { @@ -70,7 +71,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PLAIN) } } - Command.CHANGE_DISPLAY_NAME.command -> { + Command.CHANGE_DISPLAY_NAME.command -> { val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME.command.length).trim() if (newDisplayName.isNotEmpty()) { @@ -79,7 +80,42 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME) } } - Command.TOPIC.command -> { + Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command -> { + val newDisplayName = textMessage.substring(Command.CHANGE_DISPLAY_NAME_FOR_ROOM.command.length).trim() + + if (newDisplayName.isNotEmpty()) { + ParsedCommand.ChangeDisplayNameForRoom(newDisplayName) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_DISPLAY_NAME_FOR_ROOM) + } + } + Command.ROOM_AVATAR.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.isMxcUrl()) { + ParsedCommand.ChangeRoomAvatar(url) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_AVATAR) + } + } + Command.CHANGE_AVATAR_FOR_ROOM.command -> { + if (messageParts.size == 2) { + val url = messageParts[1] + + if (url.isMxcUrl()) { + ParsedCommand.ChangeAvatarForRoom(url) + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } else { + ParsedCommand.ErrorSyntax(Command.CHANGE_AVATAR_FOR_ROOM) + } + } + Command.TOPIC.command -> { val newTopic = textMessage.substring(Command.TOPIC.command.length).trim() if (newTopic.isNotEmpty()) { @@ -88,22 +124,22 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.TOPIC) } } - Command.EMOTE.command -> { + Command.EMOTE.command -> { val message = textMessage.subSequence(Command.EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendEmote(message) } - Command.RAINBOW.command -> { + Command.RAINBOW.command -> { val message = textMessage.subSequence(Command.RAINBOW.command.length, textMessage.length).trim() ParsedCommand.SendRainbow(message) } - Command.RAINBOW_EMOTE.command -> { + Command.RAINBOW_EMOTE.command -> { val message = textMessage.subSequence(Command.RAINBOW_EMOTE.command.length, textMessage.length).trim() ParsedCommand.SendRainbowEmote(message) } - Command.JOIN_ROOM.command -> { + Command.JOIN_ROOM.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -121,7 +157,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.JOIN_ROOM) } } - Command.PART.command -> { + Command.PART.command -> { if (messageParts.size >= 2) { val roomAlias = messageParts[1] @@ -139,7 +175,16 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.PART) } } - Command.INVITE.command -> { + Command.ROOM_NAME.command -> { + val newRoomName = textMessage.substring(Command.ROOM_NAME.command.length).trim() + + if (newRoomName.isNotEmpty()) { + ParsedCommand.ChangeRoomName(newRoomName) + } else { + ParsedCommand.ErrorSyntax(Command.ROOM_NAME) + } + } + Command.INVITE.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -166,7 +211,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.INVITE) } } - Command.KICK_USER.command -> { + Command.KICK_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -184,7 +229,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.KICK_USER) } } - Command.BAN_USER.command -> { + Command.BAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -202,7 +247,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.BAN_USER) } } - Command.UNBAN_USER.command -> { + Command.UNBAN_USER.command -> { if (messageParts.size >= 2) { val userId = messageParts[1] @@ -220,7 +265,33 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.UNBAN_USER) } } - Command.SET_USER_POWER_LEVEL.command -> { + Command.IGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.IgnoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.IGNORE_USER) + } + } + Command.UNIGNORE_USER.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.UnignoreUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } else { + ParsedCommand.ErrorSyntax(Command.UNIGNORE_USER) + } + } + Command.SET_USER_POWER_LEVEL.command -> { if (messageParts.size == 3) { val userId = messageParts[1] if (MatrixPatterns.isUserId(userId)) { @@ -240,7 +311,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.RESET_USER_POWER_LEVEL.command -> { + Command.RESET_USER_POWER_LEVEL.command -> { if (messageParts.size == 2) { val userId = messageParts[1] @@ -253,7 +324,7 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.SET_USER_POWER_LEVEL) } } - Command.MARKDOWN.command -> { + Command.MARKDOWN.command -> { if (messageParts.size == 2) { when { "on".equals(messageParts[1], true) -> ParsedCommand.SetMarkdown(true) @@ -264,23 +335,28 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.MARKDOWN) } } - Command.CLEAR_SCALAR_TOKEN.command -> { + Command.CLEAR_SCALAR_TOKEN.command -> { if (messageParts.size == 1) { ParsedCommand.ClearScalarToken } else { ParsedCommand.ErrorSyntax(Command.CLEAR_SCALAR_TOKEN) } } - Command.SPOILER.command -> { + Command.SPOILER.command -> { val message = textMessage.substring(Command.SPOILER.command.length).trim() ParsedCommand.SendSpoiler(message) } - Command.SHRUG.command -> { + Command.SHRUG.command -> { val message = textMessage.substring(Command.SHRUG.command.length).trim() ParsedCommand.SendShrug(message) } - Command.POLL.command -> { + Command.LENNY.command -> { + val message = textMessage.substring(Command.LENNY.command.length).trim() + + ParsedCommand.SendLenny(message) + } + Command.POLL.command -> { val rawCommand = textMessage.substring(Command.POLL.command.length).trim() val split = rawCommand.split("|").map { it.trim() } if (split.size > 2) { @@ -289,18 +365,31 @@ object CommandParser { ParsedCommand.ErrorSyntax(Command.POLL) } } - Command.DISCARD_SESSION.command -> { + Command.DISCARD_SESSION.command -> { ParsedCommand.DiscardSession } - Command.CONFETTI.command -> { + Command.WHOIS.command -> { + if (messageParts.size == 2) { + val userId = messageParts[1] + + if (MatrixPatterns.isUserId(userId)) { + ParsedCommand.ShowUser(userId) + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } else { + ParsedCommand.ErrorSyntax(Command.WHOIS) + } + } + Command.CONFETTI.command -> { val message = textMessage.substring(Command.CONFETTI.command.length).trim() ParsedCommand.SendChatEffect(ChatEffect.CONFETTI, message) } - Command.SNOWFALL.command -> { + Command.SNOWFALL.command -> { val message = textMessage.substring(Command.SNOWFALL.command.length).trim() ParsedCommand.SendChatEffect(ChatEffect.SNOWFALL, message) } - Command.CREATE_SPACE.command -> { + Command.CREATE_SPACE.command -> { val rawCommand = textMessage.substring(Command.CREATE_SPACE.command.length).trim() val split = rawCommand.split(" ").map { it.trim() } if (split.isEmpty()) { @@ -312,25 +401,25 @@ object CommandParser { ) } } - Command.ADD_TO_SPACE.command -> { + Command.ADD_TO_SPACE.command -> { val rawCommand = textMessage.substring(Command.ADD_TO_SPACE.command.length).trim() ParsedCommand.AddToSpace( rawCommand ) } - Command.JOIN_SPACE.command -> { + Command.JOIN_SPACE.command -> { val spaceIdOrAlias = textMessage.substring(Command.JOIN_SPACE.command.length).trim() ParsedCommand.JoinSpace( spaceIdOrAlias ) } - Command.LEAVE_ROOM.command -> { + Command.LEAVE_ROOM.command -> { val spaceIdOrAlias = textMessage.substring(Command.LEAVE_ROOM.command.length).trim() ParsedCommand.LeaveRoom( spaceIdOrAlias ) } - Command.UPGRADE_ROOM.command -> { + Command.UPGRADE_ROOM.command -> { val newVersion = textMessage.substring(Command.UPGRADE_ROOM.command.length).trim() if (newVersion.isEmpty()) { ParsedCommand.ErrorSyntax(Command.UPGRADE_ROOM) @@ -338,7 +427,7 @@ object CommandParser { ParsedCommand.UpgradeRoom(newVersion) } } - else -> { + else -> { // Unknown command ParsedCommand.ErrorUnknownSlashCommand(slashCommand) } diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index 123f1d3a36..bafb9153e6 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -42,7 +42,10 @@ sealed class ParsedCommand { class SendRainbowEmote(val message: CharSequence) : ParsedCommand() class BanUser(val userId: String, val reason: String?) : ParsedCommand() class UnbanUser(val userId: String, val reason: String?) : ParsedCommand() + class IgnoreUser(val userId: String) : ParsedCommand() + class UnignoreUser(val userId: String) : ParsedCommand() class SetUserPowerLevel(val userId: String, val powerLevel: Int?) : ParsedCommand() + class ChangeRoomName(val name: String) : ParsedCommand() class Invite(val userId: String, val reason: String?) : ParsedCommand() class Invite3Pid(val threePid: ThreePid) : ParsedCommand() class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() @@ -50,12 +53,17 @@ sealed class ParsedCommand { class ChangeTopic(val topic: String) : ParsedCommand() class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() + class ChangeDisplayNameForRoom(val displayName: String) : ParsedCommand() + class ChangeRoomAvatar(val url: String) : ParsedCommand() + class ChangeAvatarForRoom(val url: String) : ParsedCommand() class SetMarkdown(val enable: Boolean) : ParsedCommand() object ClearScalarToken : ParsedCommand() class SendSpoiler(val message: String) : ParsedCommand() class SendShrug(val message: CharSequence) : ParsedCommand() + class SendLenny(val message: CharSequence) : ParsedCommand() class SendPoll(val question: String, val options: List) : ParsedCommand() object DiscardSession : ParsedCommand() + class ShowUser(val userId: String) : ParsedCommand() class SendChatEffect(val chatEffect: ChatEffect, val message: String) : ParsedCommand() class CreateSpace(val name: String, val invitees: List) : ParsedCommand() class AddToSpace(val spaceId: String) : ParsedCommand() diff --git a/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt index a2d190bd69..2c19e80772 100644 --- a/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt @@ -104,8 +104,8 @@ class VectorConfiguration @Inject constructor(private val context: Context) { * @return the local status value */ fun getHash(): String { - return (VectorLocale.applicationLocale.toString() - + "_" + FontScale.getFontScaleValue(context).preferenceValue - + "_" + ThemeUtils.getApplicationTheme(context)) + return (VectorLocale.applicationLocale.toString() + + "_" + FontScale.getFontScaleValue(context).preferenceValue + + "_" + ThemeUtils.getApplicationTheme(context)) } } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt index 19024fcf8b..ea1841d870 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt @@ -31,12 +31,12 @@ import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.databinding.FragmentContactsBookBinding +import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.userdirectory.PendingSelection import im.vector.app.features.userdirectory.UserListAction import im.vector.app.features.userdirectory.UserListSharedAction import im.vector.app.features.userdirectory.UserListSharedActionViewModel import im.vector.app.features.userdirectory.UserListViewModel - import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.user.model.User import java.util.concurrent.TimeUnit @@ -75,9 +75,13 @@ class ContactsBookFragment @Inject constructor( private fun setupConsentView() { views.phoneBookSearchForMatrixContacts.setOnClickListener { withState(contactsBookViewModel) { state -> - requireContext().showIdentityServerConsentDialog(state.identityServerUrl) { - contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) - } + requireContext().showIdentityServerConsentDialog( + state.identityServerUrl, + policyLinkCallback = { + navigator.openSettings(requireContext(), SettingsActivityPayload.DiscoverySettings(expandIdentityPolicies = true)) + }, + consentCallBack = { contactsBookViewModel.handle(ContactsBookAction.UserConsentGranted) } + ) } } } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt index cfbdef8ffb..e3d996c33b 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt @@ -24,8 +24,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.contacts.ContactsDataSource import im.vector.app.core.contacts.MappedContact import im.vector.app.core.extensions.exhaustive @@ -41,8 +41,8 @@ import timber.log.Timber class ContactsBookViewModel @AssistedInject constructor(@Assisted initialState: ContactsBookViewState, private val contactsDataSource: ContactsDataSource, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -156,8 +156,8 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted val filteredMappedContacts = mappedContacts .filter { it.displayName.contains(state.searchTerm, true) } .filter { contactModel -> - !state.onlyBoundContacts - || contactModel.emails.any { it.matrixId != null } || contactModel.msisdns.any { it.matrixId != null } + !state.onlyBoundContacts || + contactModel.emails.any { it.matrixId != null } || contactModel.msisdns.any { it.matrixId != null } } setState { diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomAction.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomAction.kt index ffc25210e9..da3425d326 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomAction.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomAction.kt @@ -21,7 +21,6 @@ import im.vector.app.features.userdirectory.PendingSelection sealed class CreateDirectRoomAction : VectorViewModelAction { data class CreateRoomAndInviteSelectedUsers( - val selections: Set, - val existingDmRoomId: String? + val selections: Set ) : CreateDirectRoomAction() } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 68123d5e82..b91ecf0cfe 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -138,10 +138,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity(), UserListViewModel.Fac private fun onMenuItemSelected(action: UserListSharedAction.OnMenuItemSelected) { if (action.itemId == R.id.action_create_direct_room) { - viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers( - action.selections, - null - )) + viewModel.handle(CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(action.selections)) } } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt index 8da0147a43..5f089c6448 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt @@ -99,7 +99,6 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen Toast.makeText(requireContext(), R.string.invalid_qr_code_uri, Toast.LENGTH_SHORT).show() requireActivity().finish() } else { - val existingDm = viewModel.session.getExistingDirectRoomWithUser(mxid) // The following assumes MXIDs are case insensitive if (mxid.equals(other = viewModel.session.myUserId, ignoreCase = true)) { Toast.makeText(requireContext(), R.string.cannot_dm_self, Toast.LENGTH_SHORT).show() @@ -109,7 +108,7 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen val qrInvitee = if (viewModel.session.getUser(mxid) != null) viewModel.session.getUser(mxid)!! else User(mxid, null, null) viewModel.handle( - CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(setOf(PendingSelection.UserPendingSelection(qrInvitee)), existingDm) + CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers(setOf(PendingSelection.UserPendingSelection(qrInvitee))) ) } } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt index 88e8d68155..f192ea3019 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt @@ -24,8 +24,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel @@ -41,8 +41,8 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted initialState: CreateDirectRoomViewState, private val rawService: RawService, - val session: Session) - : VectorViewModel(initialState) { + val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -71,10 +71,13 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted * If users already have a DM room then navigate to it instead of creating a new room. */ private fun onSubmitInvitees(action: CreateDirectRoomAction.CreateRoomAndInviteSelectedUsers) { - if (action.existingDmRoomId != null) { + val existingRoomId = action.selections.singleOrNull()?.getMxId()?.let { userId -> + session.getExistingDirectRoomWithUser(userId) + } + if (existingRoomId != null) { // Do not create a new DM, just tell that the creation is successful by passing the existing roomId setState { - copy(createAndInviteState = Success(action.existingDmRoomId)) + copy(createAndInviteState = Success(existingRoomId)) } } else { // Create the DM diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index 1f8cf4d3a0..435ca6e608 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -27,12 +27,11 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startImportTextFromFileIntent import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding - import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject -class KeysBackupRestoreFromKeyFragment @Inject constructor() - : VectorBaseFragment() { +class KeysBackupRestoreFromKeyFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreFromKeyBinding { return FragmentKeysBackupRestoreFromKeyBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index 96d8a257b7..c023e66e44 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -27,7 +27,6 @@ import androidx.core.widget.doOnTextChanged import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentKeysBackupRestoreFromPassphraseBinding - import javax.inject.Inject class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt index c323024bd9..34a333d588 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt @@ -88,26 +88,26 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( override fun onStepProgress(step: StepProgressListener.Step) { when (step) { is StepProgressListener.Step.ComputingKey -> { - loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) - + "\n" + stringProvider.getString(R.string.keys_backup_restoring_computing_key_waiting_message), + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_computing_key_waiting_message), step.progress, step.total)) } is StepProgressListener.Step.DownloadingKey -> { - loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) - + "\n" + stringProvider.getString(R.string.keys_backup_restoring_downloading_backup_waiting_message), + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_downloading_backup_waiting_message), isIndeterminate = true)) } is StepProgressListener.Step.ImportingKey -> { Timber.d("backupKeys.ImportingKey.progress: ${step.progress}") // Progress 0 can take a while, display an indeterminate progress in this case if (step.progress == 0) { - loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) - + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message), + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message), isIndeterminate = true)) } else { - loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) - + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message), + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_importing_keys_waiting_message), step.progress, step.total)) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index 8c1124bbbc..66a7df14c3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -24,7 +24,6 @@ import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.LiveEvent import im.vector.app.databinding.FragmentKeysBackupRestoreSuccessBinding - import javax.inject.Inject class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt index 874e3765ca..fa701f2810 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt @@ -26,5 +26,5 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionR data class KeysBackupSettingViewState(val keysBackupVersionTrust: Async = Uninitialized, val keysBackupState: KeysBackupState? = null, val keysBackupVersion: KeysVersionResult? = null, - val deleteBackupRequest: Async = Uninitialized) - : MvRxState + val deleteBackupRequest: Async = Uninitialized) : + MvRxState diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt index d2ee1bd637..cf6bd99f23 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt @@ -29,11 +29,10 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentKeysBackupSettingsBinding import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity - import javax.inject.Inject -class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController) - : VectorBaseFragment(), +class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController) : + VectorBaseFragment(), KeysBackupSettingsRecyclerViewController.Listener { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSettingsBinding { 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 cb8a6ce4e9..d47416dd38 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 @@ -23,8 +23,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.MatrixCallback @@ -163,7 +163,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS fun canExit(): Boolean { val currentBackupState = keysBackupService.state - return currentBackupState == KeysBackupState.Unknown - || currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver + return currentBackupState == KeysBackupState.Unknown || + currentBackupState == KeysBackupState.CheckingBackUpOnHomeserver } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index cf65a9942c..08496c490f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -23,7 +23,6 @@ import android.view.ViewGroup import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.LiveEvent import im.vector.app.databinding.FragmentKeysBackupSetupStep1Binding - import javax.inject.Inject class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 5739da11bb..2befc4e79d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -36,7 +36,6 @@ import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.selectTxtFileToWrite import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentKeysBackupSetupStep3Binding - import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt index a961c31292..85250a94ce 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt @@ -226,9 +226,9 @@ class KeyRequestHandler @Inject constructor( val alertMgrUniqueKey = alertManagerId(userId, deviceId) alertsToRequests[alertMgrUniqueKey]?.removeAll { - it.deviceId == request.deviceId - && it.userId == request.userId - && it.requestId == request.requestId + it.deviceId == request.deviceId && + it.userId == request.userId && + it.requestId == request.requestId } if (alertsToRequests[alertMgrUniqueKey]?.isEmpty() == true) { popupAlertManager.cancelAlert(alertMgrUniqueKey) diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index 9a5fc4ca06..e3258c40ec 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -27,8 +27,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -67,8 +67,8 @@ class SharedSecureStorageViewModel @AssistedInject constructor( @Assisted initialState: SharedSecureStorageViewState, @Assisted val args: SharedSecureStorageActivity.Args, private val stringProvider: StringProvider, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -76,7 +76,6 @@ class SharedSecureStorageViewModel @AssistedInject constructor( } init { - setState { copy(userId = session.myUserId) } @@ -167,10 +166,14 @@ class SharedSecureStorageViewModel @AssistedInject constructor( if (state.checkingSSSSAction is Loading) return@withState // ignore when (state.step) { SharedSecureStorageViewState.Step.EnterKey -> { - setState { - copy( - step = SharedSecureStorageViewState.Step.EnterPassphrase - ) + if (state.hasPassphrase) { + setState { + copy( + step = SharedSecureStorageViewState.Step.EnterPassphrase + ) + } + } else { + _viewEvents.post(SharedSecureStorageViewEvent.Dismiss) } } SharedSecureStorageViewState.Step.ResetAll -> { diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt index feff326cfd..1ba0198cb4 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt @@ -31,7 +31,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startImportTextFromFileIntent import im.vector.app.databinding.FragmentSsssAccessFromKeyBinding import io.reactivex.android.schedulers.AndroidSchedulers - import org.matrix.android.sdk.api.extensions.tryOrNull import java.util.concurrent.TimeUnit import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt index b640577797..670e5c610a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt @@ -27,11 +27,10 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentSsssResetAllBinding import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet - import javax.inject.Inject -class SharedSecuredStorageResetAllFragment @Inject constructor() - : VectorBaseFragment() { +class SharedSecuredStorageResetAllFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssResetAllBinding { return FragmentSsssResetAllBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapActions.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapActions.kt index 869f0ed8ec..363416b7de 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapActions.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapActions.kt @@ -36,6 +36,7 @@ sealed class BootstrapActions : VectorViewModelAction { object DoInitializeGeneratedKey : BootstrapActions() data class UpdateCandidatePassphrase(val pass: String) : BootstrapActions() data class UpdateConfirmCandidatePassphrase(val pass: String) : BootstrapActions() + // data class ReAuth(val pass: String) : BootstrapActions() object RecoveryKeySaved : BootstrapActions() object Completed : BootstrapActions() @@ -47,7 +48,7 @@ sealed class BootstrapActions : VectorViewModelAction { data class DoMigrateWithPassphrase(val passphrase: String) : BootstrapActions() data class DoMigrateWithRecoveryKey(val recoveryKey: String) : BootstrapActions() - object SsoAuthDone: BootstrapActions() - data class PasswordAuthDone(val password: String): BootstrapActions() - object ReAuthCancelled: BootstrapActions() + object SsoAuthDone : BootstrapActions() + data class PasswordAuthDone(val password: String) : BootstrapActions() + object ReAuthCancelled : BootstrapActions() } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt index 6c5c259755..555f2d7c1c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt @@ -28,7 +28,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.databinding.FragmentBootstrapConclusionBinding - import javax.inject.Inject class BootstrapConclusionFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt index 602f0bad91..4aeb822bbd 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt @@ -31,12 +31,11 @@ import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding import io.reactivex.android.schedulers.AndroidSchedulers - import java.util.concurrent.TimeUnit import javax.inject.Inject -class BootstrapConfirmPassphraseFragment @Inject constructor() - : VectorBaseFragment() { +class BootstrapConfirmPassphraseFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterPassphraseBinding { return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false) 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 70cda4bf79..cc863346aa 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 @@ -81,9 +81,9 @@ class BootstrapCrossSigningTask @Inject constructor( Timber.d("## BootstrapCrossSigningTask: mode:${params.setupMode} Starting...") // Ensure cross-signing is initialized. Due to migration it is maybe not always correctly initialized - val shouldSetCrossSigning = !crossSigningService.isCrossSigningInitialized() - || (params.setupMode == SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET && !crossSigningService.allPrivateKeysKnown()) - || (params.setupMode == SetupMode.HARD_RESET) + val shouldSetCrossSigning = !crossSigningService.isCrossSigningInitialized() || + (params.setupMode == SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET && !crossSigningService.allPrivateKeysKnown()) || + (params.setupMode == SetupMode.HARD_RESET) if (shouldSetCrossSigning) { Timber.d("## BootstrapCrossSigningTask: Cross signing not enabled, so initialize") params.progressListener?.onProgress( @@ -227,9 +227,9 @@ class BootstrapCrossSigningTask @Inject constructor( val knownMegolmSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() val isMegolmBackupSecretKnown = knownMegolmSecret != null && knownMegolmSecret.version == serverVersion?.version - val shouldCreateKeyBackup = serverVersion == null - || (params.setupMode == SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET && !isMegolmBackupSecretKnown) - || (params.setupMode == SetupMode.HARD_RESET) + val shouldCreateKeyBackup = serverVersion == null || + (params.setupMode == SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET && !isMegolmBackupSecretKnown) || + (params.setupMode == SetupMode.HARD_RESET) if (shouldCreateKeyBackup) { // clear all existing backups while (serverVersion != null) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt index 9ecc7719a5..f43ddb8888 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt @@ -30,12 +30,11 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding import im.vector.app.features.settings.VectorLocale import io.reactivex.android.schedulers.AndroidSchedulers - import java.util.concurrent.TimeUnit import javax.inject.Inject -class BootstrapEnterPassphraseFragment @Inject constructor() - : VectorBaseFragment() { +class BootstrapEnterPassphraseFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterPassphraseBinding { return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt index 23d3068e34..b40a194a15 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt @@ -40,7 +40,6 @@ import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.core.utils.startImportTextFromFileIntent import im.vector.app.databinding.FragmentBootstrapMigrateBackupBinding import io.reactivex.android.schedulers.AndroidSchedulers - import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.internal.crypto.keysbackup.util.isValidRecoveryKey import java.util.concurrent.TimeUnit diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapReAuthFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapReAuthFragment.kt index 507050c2e8..c46ccbf08e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapReAuthFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapReAuthFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentBootstrapReauthBinding - import javax.inject.Inject class BootstrapReAuthFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt index 0e11c35289..8a41c7ce4d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt @@ -34,7 +34,6 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.FragmentBootstrapSaveKeyBinding - import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt index 8676f1fb6b..2765dfefd3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt @@ -26,11 +26,10 @@ import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentBootstrapSetupRecoveryBinding - import javax.inject.Inject -class BootstrapSetupRecoveryKeyFragment @Inject constructor() - : VectorBaseFragment() { +class BootstrapSetupRecoveryKeyFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapSetupRecoveryBinding { return FragmentBootstrapSetupRecoveryBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index 866a87d7f9..17a1359ea6 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -38,19 +38,19 @@ import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.login.ReAuthHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec -import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse -import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.api.auth.UIABaseAuth -import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.internal.util.awaitCallback import java.io.OutputStream import kotlin.coroutines.Continuation @@ -437,9 +437,9 @@ class BootstrapSharedViewModel @AssistedInject constructor( } } is BootstrapResult.Failure -> { - if (bootstrapResult is BootstrapResult.GenericError - && bootstrapResult.failure is Failure.OtherServerError - && bootstrapResult.failure.httpCode == 401) { + if (bootstrapResult is BootstrapResult.GenericError && + bootstrapResult.failure is Failure.OtherServerError && + bootstrapResult.failure.httpCode == 401) { // Ignore this error } else { _viewEvents.post(BootstrapViewEvents.ModalError(bootstrapResult.error ?: stringProvider.getString(R.string.matrix_error))) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt index 7852ff172c..8cf48a7c66 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt @@ -23,11 +23,10 @@ import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentBootstrapWaitingBinding - import javax.inject.Inject -class BootstrapWaitingFragment @Inject constructor() - : VectorBaseFragment() { +class BootstrapWaitingFragment @Inject constructor() : + VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapWaitingBinding { return FragmentBootstrapWaitingBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index 0b93120b52..6c009d3786 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -18,6 +18,7 @@ package im.vector.app.features.crypto.verification import android.content.Context import im.vector.app.R import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailArgs @@ -63,7 +64,7 @@ class IncomingVerificationRequestHandler @Inject constructor( is VerificationTxState.OnStarted -> { // Add a notification for every incoming request val user = session?.getUser(tx.otherUserId) - val name = user?.getBestName() ?: tx.otherUserId + val name = user?.toMatrixItem()?.getBestName() ?: tx.otherUserId val alert = VerificationVectorAlert( uid, context.getString(R.string.sas_incoming_request_notif_title), diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index 47033199f4..3b392780ef 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -45,6 +45,7 @@ import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeFra import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQRWaitingFragment import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrScannedByOtherFragment import im.vector.app.features.crypto.verification.request.VerificationRequestFragment +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.settings.VectorSettingsActivity import kotlinx.parcelize.Parcelize @@ -159,9 +160,9 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment if (state.isMe) { avatarRenderer.render(matrixItem, views.otherUserAvatarImageView) - if (state.sasTransactionState == VerificationTxState.Verified - || state.qrTransactionState == VerificationTxState.Verified - || state.verifiedFromPrivateKeys) { + if (state.sasTransactionState == VerificationTxState.Verified || + state.qrTransactionState == VerificationTxState.Verified || + state.verifiedFromPrivateKeys) { views.otherUserShield.render(RoomEncryptionTrustLevel.Trusted) } else { views.otherUserShield.render(RoomEncryptionTrustLevel.Warning) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 8e21412715..4a29f883c0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -26,8 +26,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -86,8 +86,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( @Assisted val args: VerificationBottomSheet.VerificationArgs, private val session: Session, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, - private val stringProvider: StringProvider) - : VectorViewModel(initialState), + private val stringProvider: StringProvider) : + VectorViewModel(initialState), VerificationService.Listener { init { @@ -172,9 +172,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } else { // if the verification is already done you can't cancel anymore - if (state.pendingRequest.invoke()?.cancelConclusion != null - || state.sasTransactionState is VerificationTxState.TerminalTxState - || state.verifyingFrom4S) { + if (state.pendingRequest.invoke()?.cancelConclusion != null || + state.sasTransactionState is VerificationTxState.TerminalTxState || + state.verifyingFrom4S) { // you cannot cancel anymore } else { setState { @@ -537,9 +537,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } - if (pr.localId == state.pendingLocalId - || pr.localId == state.pendingRequest.invoke()?.localId - || state.pendingRequest.invoke()?.transactionId == pr.transactionId) { + if (pr.localId == state.pendingLocalId || + pr.localId == state.pendingRequest.invoke()?.localId || + state.pendingRequest.invoke()?.transactionId == pr.transactionId) { setState { copy( transactionId = args.verificationId ?: pr.transactionId, diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt index 497617f1ad..62bab05e42 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel - import javax.inject.Inject class VerificationCancelFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt index 46cb3a97a2..635a56a6c1 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel - import javax.inject.Inject class VerificationNotMeFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt index d3f24816a5..92faa7a0e7 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt @@ -36,7 +36,6 @@ import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel import im.vector.app.features.qrcode.QrCodeScannerActivity - import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index 7b9acd2f57..a6825348e9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -20,8 +20,8 @@ import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionViewModel.kt index 50912af1c2..2708aa0961 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionViewModel.kt @@ -35,8 +35,8 @@ enum class ConclusionState { CANCELLED } -class VerificationConclusionViewModel(initialState: VerificationConclusionViewState) - : VectorViewModel(initialState) { +class VerificationConclusionViewModel(initialState: VerificationConclusionViewState) : + VectorViewModel(initialState) { companion object : MvRxViewModelFactory { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt index 5159a69090..eab53ea954 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt @@ -30,6 +30,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationD import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationEmojisItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem +import im.vector.app.features.displayname.getBestName import javax.inject.Inject class VerificationEmojiCodeController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt index 97f521ee72..566307c05b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt @@ -28,7 +28,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel - import javax.inject.Inject class VerificationEmojiCodeFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index 44f0e752c8..1795d120f3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -25,8 +25,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt index 01862a5ab4..f3990842f9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt @@ -25,6 +25,7 @@ import im.vector.app.features.crypto.verification.VerificationBottomSheetViewSta import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationBigImageItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem +import im.vector.app.features.displayname.getBestName import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt index 2ef015edbc..9e77506e3b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel - import javax.inject.Inject class VerificationQrScannedByOtherFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt index 260bcf597e..6440c0032b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt @@ -31,6 +31,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetSelfWaitItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem +import im.vector.app.features.displayname.getBestName import javax.inject.Inject class VerificationRequestController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt index 479dc7b3c7..238249683f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel - import javax.inject.Inject class VerificationRequestFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt index 36ccef1fca..bcdcf5f719 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -194,8 +194,8 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto state.displayMode is RoomDevToolViewState.Mode.StateEventDetail } R.id.menuItemSend -> { - state.displayMode is RoomDevToolViewState.Mode.EditEventContent - || state.displayMode is RoomDevToolViewState.Mode.SendEventForm + state.displayMode is RoomDevToolViewState.Mode.EditEventContent || + state.displayMode is RoomDevToolViewState.Mode.SendEventForm } else -> true } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt index 98fe19a765..9af51f67b3 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt @@ -28,8 +28,8 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentDevtoolsEditorBinding import javax.inject.Inject -class RoomDevToolEditFragment @Inject constructor() - : VectorBaseFragment() { +class RoomDevToolEditFragment @Inject constructor() : + VectorBaseFragment() { private val sharedViewModel: RoomDevToolViewModel by activityViewModel() diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt new file mode 100644 index 0000000000..c97a2286ae --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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.discovery + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.airbnb.epoxy.EpoxyModelWithHolder +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.onClick + +@EpoxyModelClass(layout = R.layout.item_discovery_policy) +abstract class DiscoveryPolicyItem : EpoxyModelWithHolder() { + + @EpoxyAttribute + var name: String? = null + + @EpoxyAttribute + var url: String? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.title.text = name + holder.url.text = url + holder.view.onClick(clickListener) + } + + class Holder : VectorEpoxyHolder() { + val title by bind(R.id.discovery_policy_name) + val url by bind(R.id.discovery_policy_url) + } +} diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsAction.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsAction.kt index 426f1321e7..a2f855c499 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsAction.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsAction.kt @@ -31,4 +31,5 @@ sealed class DiscoverySettingsAction : VectorViewModelAction { data class FinalizeBind3pid(val threePid: ThreePid) : DiscoverySettingsAction() data class SubmitMsisdnToken(val threePid: ThreePid.Msisdn, val code: String) : DiscoverySettingsAction() data class CancelBinding(val threePid: ThreePid) : DiscoverySettingsAction() + data class SetPoliciesExpandState(val expanded: Boolean) : DiscoverySettingsAction() } diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt index 1e8db2571d..d8c67592f1 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt @@ -31,6 +31,7 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.getFormattedValue import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider +import im.vector.app.features.form.formAdvancedToggleItem import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid @@ -62,7 +63,7 @@ class DiscoverySettingsController @Inject constructor( } is Success -> { buildIdentityServerSection(data) - val hasIdentityServer = data.identityServer().isNullOrBlank().not() + val hasIdentityServer = data.identityServer()?.serverUrl.isNullOrBlank().not() if (hasIdentityServer && !data.termsNotSigned) { buildConsentSection(data) buildEmailsSection(data.emailList) @@ -106,7 +107,8 @@ class DiscoverySettingsController @Inject constructor( } private fun buildIdentityServerSection(data: DiscoverySettingsState) { - val identityServer = data.identityServer() ?: stringProvider.getString(R.string.none) + val identityServer = data.identityServer() + val identityServerUrl = identityServer?.serverUrl ?: stringProvider.getString(R.string.none) val host = this settingsSectionTitleItem { @@ -116,28 +118,58 @@ class DiscoverySettingsController @Inject constructor( settingsItem { id("idServer") - title(identityServer) + title(identityServerUrl) } - if (data.identityServer() != null && data.termsNotSigned) { + val policies = identityServer?.policies + if (policies != null) { + formAdvancedToggleItem { + id("policy-urls") + val titleRes = if (data.isIdentityPolicyUrlsExpanded) { + R.string.settings_discovery_hide_identity_server_policy_title + } else R.string.settings_discovery_show_identity_server_policy_title + title(host.stringProvider.getString(titleRes)) + expanded(data.isIdentityPolicyUrlsExpanded) + listener { host.listener?.onPolicyUrlsExpandedStateToggled(!data.isIdentityPolicyUrlsExpanded) } + } + if (data.isIdentityPolicyUrlsExpanded) { + if (policies.isEmpty()) { + settingsInfoItem { + id("emptyPolicy") + helperText(host.stringProvider.getString(R.string.settings_discovery_no_policy_provided)) + } + } else { + policies.forEach { policy -> + discoveryPolicyItem { + id(policy.url) + name(policy.name) + url(policy.url) + clickListener { host.listener?.onPolicyTapped(policy) } + } + } + } + } + } + + if (identityServer != null && data.termsNotSigned) { settingsInfoItem { id("idServerFooter") - helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer)) + helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServerUrl)) showCompoundDrawable(true) itemClickListener { host.listener?.openIdentityServerTerms() } } settingsButtonItem { id("seeTerms") colorProvider(host.colorProvider) - buttonTitle(host.stringProvider.getString(R.string.open_terms_of, identityServer)) + buttonTitle(host.stringProvider.getString(R.string.open_terms_of, identityServerUrl)) buttonClickListener { host.listener?.openIdentityServerTerms() } } } else { settingsInfoItem { id("idServerFooter") showCompoundDrawable(false) - if (data.identityServer() != null) { - helperText(host.stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServer)) + if (identityServer != null) { + helperText(host.stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServerUrl)) } else { helperTextResId(R.string.settings_discovery_identity_server_info_none) } @@ -147,7 +179,7 @@ class DiscoverySettingsController @Inject constructor( settingsButtonItem { id("change") colorProvider(host.colorProvider) - if (data.identityServer() == null) { + if (identityServer == null) { buttonTitleId(R.string.add_identity_server) } else { buttonTitleId(R.string.change_identity_server) @@ -155,7 +187,7 @@ class DiscoverySettingsController @Inject constructor( buttonClickListener { host.listener?.onTapChangeIdentityServer() } } - if (data.identityServer() != null) { + if (identityServer != null) { settingsInfoItem { id("removeInfo") helperTextResId(R.string.settings_discovery_disconnect_identity_server_info) @@ -282,8 +314,8 @@ class DiscoverySettingsController @Inject constructor( val error = pidInfo.finalRequest.error // Deal with error 500 // Ref: https://github.com/matrix-org/sydent/issues/292 - if (error is Failure.ServerError - && error.httpCode == HttpsURLConnection.HTTP_INTERNAL_ERROR /* 500 */) { + if (error is Failure.ServerError && + error.httpCode == HttpsURLConnection.HTTP_INTERNAL_ERROR /* 500 */) { stringProvider.getString(R.string.settings_text_message_sent_wrong_code) } else { errorFormatter.toHumanReadable(error) @@ -400,5 +432,7 @@ class DiscoverySettingsController @Inject constructor( fun onTapDisconnectIdentityServer() fun onTapUpdateUserConsent(newValue: Boolean) fun onTapRetryToRetrieveBindings() + fun onPolicyUrlsExpandedStateToggled(newExpandedState: Boolean) + fun onPolicyTapped(policy: IdentityServerPolicy) } } diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt index 41b83c627d..6de7c1fba5 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt @@ -21,6 +21,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -32,11 +33,12 @@ import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.ensureProtocol +import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.discovery.change.SetIdentityServerFragment +import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.settings.VectorSettingsActivity - import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.terms.TermsService @@ -53,6 +55,7 @@ class DiscoverySettingsFragment @Inject constructor( } private val viewModel by fragmentViewModel(DiscoverySettingsViewModel::class) + private val discoveryArgs: SettingsActivityPayload.DiscoverySettings by args() lateinit var sharedViewModel: DiscoverySharedViewModel @@ -78,6 +81,9 @@ class DiscoverySettingsFragment @Inject constructor( } }.exhaustive } + if (discoveryArgs.expandIdentityPolicies) { + viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = true)) + } } override fun onDestroyView() { @@ -112,7 +118,7 @@ class DiscoverySettingsFragment @Inject constructor( requireContext(), termsActivityResultLauncher, TermsService.ServiceType.IdentityService, - state.identityServer()?.ensureProtocol() ?: "", + state.identityServer()?.serverUrl?.ensureProtocol() ?: "", null) } } @@ -180,9 +186,11 @@ class DiscoverySettingsFragment @Inject constructor( override fun onTapUpdateUserConsent(newValue: Boolean) { if (newValue) { withState(viewModel) { state -> - requireContext().showIdentityServerConsentDialog(state.identityServer.invoke()) { - viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(true)) - } + requireContext().showIdentityServerConsentDialog( + state.identityServer.invoke()?.serverUrl, + policyLinkCallback = { viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = true)) }, + consentCallBack = { viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(true)) } + ) } } else { viewModel.handle(DiscoverySettingsAction.UpdateUserConsent(false)) @@ -193,6 +201,14 @@ class DiscoverySettingsFragment @Inject constructor( viewModel.handle(DiscoverySettingsAction.RetrieveBinding) } + override fun onPolicyUrlsExpandedStateToggled(newExpandedState: Boolean) { + viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = newExpandedState)) + } + + override fun onPolicyTapped(policy: IdentityServerPolicy) { + openUrlInChromeCustomTab(requireContext(), null, policy.url) + } + private fun navigateToChangeIdentityServerFragment() { (vectorBaseActivity as? VectorSettingsActivity)?.navigateTo(SetIdentityServerFragment::class.java) } diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt index 21fbcf1ca7..1d7346e463 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsState.kt @@ -21,10 +21,18 @@ import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.Uninitialized data class DiscoverySettingsState( - val identityServer: Async = Uninitialized, + val identityServer: Async = Uninitialized, val emailList: Async> = Uninitialized, val phoneNumbersList: Async> = Uninitialized, // Can be true if terms are updated val termsNotSigned: Boolean = false, - val userConsent: Boolean = false + val userConsent: Boolean = false, + val isIdentityPolicyUrlsExpanded: Boolean = false ) : MvRxState + +data class IdentityServerWithTerms( + val serverUrl: String, + val policies: List +) + +data class IdentityServerPolicy(val name: String, val url: String) diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt index 3cd6c31ab2..8b454607d5 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt @@ -25,22 +25,27 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.ensureProtocol import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.IdentityServiceListener import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid +import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.rx.rx class DiscoverySettingsViewModel @AssistedInject constructor( @Assisted initialState: DiscoverySettingsState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session, + private val stringProvider: StringProvider +) : VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -57,25 +62,32 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } private val identityService = session.identityService() + private val termsService: TermsService = session private val identityServerManagerListener = object : IdentityServiceListener { override fun onIdentityServerChange() = withState { state -> - val identityServerUrl = identityService.getCurrentIdentityServerUrl() - val currentIS = state.identityServer() - setState { - copy( - identityServer = Success(identityServerUrl), - userConsent = identityService.getUserConsent() + viewModelScope.launch { + runCatching { fetchIdentityServerWithTerms() }.fold( + onSuccess = { + val currentIS = state.identityServer() + setState { + copy( + identityServer = Success(it), + userConsent = identityService.getUserConsent() + ) + } + if (currentIS != it) retrieveBinding() + }, + onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) } ) } - if (currentIS != identityServerUrl) retrieveBinding() } } init { setState { copy( - identityServer = Success(identityService.getCurrentIdentityServerUrl()), + identityServer = Success(identityService.getCurrentIdentityServerUrl()?.let { IdentityServerWithTerms(it, emptyList()) }), userConsent = identityService.getUserConsent() ) } @@ -99,16 +111,17 @@ class DiscoverySettingsViewModel @AssistedInject constructor( override fun handle(action: DiscoverySettingsAction) { when (action) { - DiscoverySettingsAction.Refresh -> refreshPendingEmailBindings() - DiscoverySettingsAction.RetrieveBinding -> retrieveBinding() - DiscoverySettingsAction.DisconnectIdentityServer -> disconnectIdentityServer() - is DiscoverySettingsAction.ChangeIdentityServer -> changeIdentityServer(action) - is DiscoverySettingsAction.UpdateUserConsent -> handleUpdateUserConsent(action) - is DiscoverySettingsAction.RevokeThreePid -> revokeThreePid(action) - is DiscoverySettingsAction.ShareThreePid -> shareThreePid(action) - is DiscoverySettingsAction.FinalizeBind3pid -> finalizeBind3pid(action, true) - is DiscoverySettingsAction.SubmitMsisdnToken -> submitMsisdnToken(action) - is DiscoverySettingsAction.CancelBinding -> cancelBinding(action) + DiscoverySettingsAction.Refresh -> fetchContent() + DiscoverySettingsAction.RetrieveBinding -> retrieveBinding() + DiscoverySettingsAction.DisconnectIdentityServer -> disconnectIdentityServer() + is DiscoverySettingsAction.SetPoliciesExpandState -> updatePolicyUrlsExpandedState(action.expanded) + is DiscoverySettingsAction.ChangeIdentityServer -> changeIdentityServer(action) + is DiscoverySettingsAction.UpdateUserConsent -> handleUpdateUserConsent(action) + is DiscoverySettingsAction.RevokeThreePid -> revokeThreePid(action) + is DiscoverySettingsAction.ShareThreePid -> shareThreePid(action) + is DiscoverySettingsAction.FinalizeBind3pid -> finalizeBind3pid(action, true) + is DiscoverySettingsAction.SubmitMsisdnToken -> submitMsisdnToken(action) + is DiscoverySettingsAction.CancelBinding -> cancelBinding(action) }.exhaustive } @@ -135,6 +148,10 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } } + private fun updatePolicyUrlsExpandedState(isExpanded: Boolean) { + setState { copy(isIdentityPolicyUrlsExpanded = isExpanded) } + } + private fun changeIdentityServer(action: DiscoverySettingsAction.ChangeIdentityServer) { setState { copy(identityServer = Loading()) } @@ -143,7 +160,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor( val data = session.identityService().setNewIdentityServer(action.url) setState { copy( - identityServer = Success(data), + identityServer = Success(IdentityServerWithTerms(data, emptyList())), userConsent = false ) } @@ -287,7 +304,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } private fun retrieveBinding(threePids: List) = withState { state -> - if (state.identityServer().isNullOrBlank()) return@withState + if (state.identityServer()?.serverUrl.isNullOrBlank()) return@withState val emails = threePids.filterIsInstance() val msisdns = threePids.filterIsInstance() @@ -335,7 +352,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } private fun submitMsisdnToken(action: DiscoverySettingsAction.SubmitMsisdnToken) = withState { state -> - if (state.identityServer().isNullOrBlank()) return@withState + if (state.identityServer()?.serverUrl.isNullOrBlank()) return@withState changeThreePidSubmitState(action.threePid, Loading()) @@ -378,12 +395,37 @@ class DiscoverySettingsViewModel @AssistedInject constructor( } } - private fun refreshPendingEmailBindings() = withState { state -> + private fun fetchContent() = withState { state -> state.emailList()?.forEach { info -> when (info.isShared()) { SharedState.BINDING_IN_PROGRESS -> finalizeBind3pid(DiscoverySettingsAction.FinalizeBind3pid(info.threePid), false) else -> Unit } } + viewModelScope.launch { + runCatching { fetchIdentityServerWithTerms() }.fold( + onSuccess = { setState { copy(identityServer = Success(it)) } }, + onFailure = { _viewEvents.post(DiscoverySettingsViewEvents.Failure(it)) } + ) + } + } + + private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms? { + val identityServerUrl = identityService.getCurrentIdentityServerUrl() + return identityServerUrl?.let { + val terms = termsService.getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol()) + .serverResponse + .getLocalizedTerms(stringProvider.getString(R.string.resources_language)) + val policyUrls = terms.mapNotNull { + val name = it.localizedName ?: it.policyName + val url = it.localizedUrl + if (name == null || url == null) { + null + } else { + IdentityServerPolicy(name = name, url = url) + } + } + IdentityServerWithTerms(identityServerUrl, policyUrls) + } } } diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt index 36e77fb6a0..dd4db36387 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt @@ -37,7 +37,6 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.databinding.FragmentSetIdentityServerBinding import im.vector.app.features.discovery.DiscoverySharedViewModel - import org.matrix.android.sdk.api.session.terms.TermsService import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt index 08632a2bd1..a63ec22110 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt @@ -20,8 +20,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.extensions.exhaustive @@ -38,8 +38,8 @@ import java.net.UnknownHostException class SetIdentityServerViewModel @AssistedInject constructor( @Assisted initialState: SetIdentityServerState, private val mxSession: Session, - stringProvider: StringProvider) - : VectorViewModel(initialState) { + stringProvider: StringProvider) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/displayname/Extension.kt b/vector/src/main/java/im/vector/app/features/displayname/Extension.kt new file mode 100644 index 0000000000..6ca1d48464 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/displayname/Extension.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 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.displayname + +import org.matrix.android.sdk.api.util.MatrixItem + +fun MatrixItem.getBestName(): String { + // Note: this code is copied from [DisplayNameResolver] in the SDK + return if (this is MatrixItem.GroupItem || this is MatrixItem.RoomAliasItem) { + // Best name is the id, and we keep the displayName of the room for the case we need the first letter + id + } else { + displayName + ?.takeIf { it.isNotBlank() } + ?: VectorMatrixItemDisplayNameFallbackProvider.getDefaultName(this) + } +} diff --git a/vector/src/main/java/im/vector/app/features/displayname/VectorMatrixItemDisplayNameFallbackProvider.kt b/vector/src/main/java/im/vector/app/features/displayname/VectorMatrixItemDisplayNameFallbackProvider.kt new file mode 100644 index 0000000000..23b55335b8 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/displayname/VectorMatrixItemDisplayNameFallbackProvider.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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.displayname + +import org.matrix.android.sdk.api.MatrixItemDisplayNameFallbackProvider +import org.matrix.android.sdk.api.util.MatrixItem + +// Used to provide the fallback to the MatrixSDK, in the MatrixConfiguration +object VectorMatrixItemDisplayNameFallbackProvider : MatrixItemDisplayNameFallbackProvider { + override fun getDefaultName(matrixItem: MatrixItem): String { + // Can customize something from the id if necessary here + return matrixItem.id + } +} diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index 2b2fddd0c9..cda1623c88 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -17,6 +17,7 @@ package im.vector.app.features.form import android.text.Editable +import android.text.InputFilter import android.view.View import android.view.inputmethod.EditorInfo import android.widget.TextView @@ -77,6 +78,9 @@ abstract class FormEditTextItem : VectorEpoxyModel() { @EpoxyAttribute var suffixText: String? = null + @EpoxyAttribute + var maxLength: Int? = null + private val onTextChangeListener = object : SimpleTextWatcher() { override fun afterTextChanged(s: Editable) { onTextChange?.invoke(s.toString()) @@ -109,6 +113,15 @@ abstract class FormEditTextItem : VectorEpoxyModel() { holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener) holder.textInputEditText.setOnEditorActionListener(editorActionListener) holder.textInputEditText.onFocusChangeListener = onFocusChangedListener + + if (maxLength != null) { + holder.textInputEditText.filters = arrayOf(InputFilter.LengthFilter(maxLength!!)) + holder.textInputLayout.isCounterEnabled = true + holder.textInputLayout.counterMaxLength = maxLength!! + } else { + holder.textInputEditText.filters = arrayOf() + holder.textInputLayout.isCounterEnabled = false + } } override fun shouldSaveViewState(): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt b/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt index bbced2e8e1..bd414c0c3f 100644 --- a/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/grouplist/HomeSpaceSummaryItem.kt @@ -39,7 +39,7 @@ abstract class HomeSpaceSummaryItem : VectorEpoxyModel val resolvedLink = when { - deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink - deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { - // This is a bit ugly, but for now just convert to matrix.to link for compatibility - when { + // Element custom scheme is not handled by the sdk, convert it to matrix.to link for compatibility + deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> { + val let = when { deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length) deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length) else -> null - }?.let { - activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it) + }?.let { permalinkId -> + activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId) } + let } - else -> return@let + else -> deepLink } - permalinkHandler.launch( context = this, deepLink = resolvedLink, @@ -296,9 +318,11 @@ class HomeActivity : .observeOn(AndroidSchedulers.mainThread()) .subscribe { isHandled -> if (!isHandled) { + val isMatrixToLink = deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) || + deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) MaterialAlertDialogBuilder(this) .setTitle(R.string.dialog_title_error) - .setMessage(R.string.permalink_malformed) + .setMessage(if (isMatrixToLink) R.string.permalink_malformed else R.string.universal_link_malformed) .setPositiveButton(R.string.ok, null) .show() } @@ -309,10 +333,7 @@ class HomeActivity : private fun renderState(state: HomeActivityViewState) { when (val status = state.syncStatusServiceStatus) { - is SyncStatusService.Status.Idle -> { - views.waitingView.root.isVisible = false - } - is SyncStatusService.Status.Progressing -> { + is SyncStatusService.Status.Progressing -> { val initSyncStepStr = initSyncStepFormatter.format(status.initSyncStep) Timber.v("$initSyncStepStr ${status.percentProgress}") views.waitingView.root.setOnClickListener { @@ -330,7 +351,10 @@ class HomeActivity : } views.waitingView.root.isVisible = true } - else -> Unit + else -> { + // Idle or Incremental sync status + views.waitingView.root.isVisible = false + } }.exhaustive } @@ -445,6 +469,7 @@ class HomeActivity : override fun onDestroy() { views.drawerLayout.removeDrawerListener(drawerListener) + supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) super.onDestroy() } @@ -526,30 +551,15 @@ class HomeActivity : } override fun navToMemberProfile(userId: String, deepLink: Uri): Boolean { - val listener = object : MatrixToBottomSheet.InteractionListener { - override fun navigateToRoom(roomId: String) { - navigator.openRoom(this@HomeActivity, roomId) - } - } // TODO check if there is already one?? - MatrixToBottomSheet.withLink(deepLink.toString(), listener) + MatrixToBottomSheet.withLink(deepLink.toString()) .show(supportFragmentManager, "HA#MatrixToBottomSheet") return true } override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean { if (roomId == null) return false - val listener = object : MatrixToBottomSheet.InteractionListener { - override fun navigateToRoom(roomId: String) { - navigator.openRoom(this@HomeActivity, roomId) - } - - override fun switchToSpace(spaceId: String) { - navigator.switchToSpace(this@HomeActivity, spaceId, Navigator.PostSwitchSpaceAction.None) - } - } - - MatrixToBottomSheet.withLink(deepLink.toString(), listener) + MatrixToBottomSheet.withLink(deepLink.toString()) .show(supportFragmentManager, "HA#MatrixToBottomSheet") return true } @@ -579,11 +589,15 @@ class HomeActivity : putExtra(MvRx.KEY_ARG, args) } } - - private const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" - private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" - private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" } override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState) + + override fun mxToBottomSheetNavigateToRoom(roomId: String) { + navigator.openRoom(this, roomId) + } + + override fun mxToBottomSheetSwitchToSpace(spaceId: String) { + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 1aa2f59337..be8b0cbc61 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -218,9 +218,9 @@ class HomeActivityViewModel @AssistedInject constructor( object : UserInteractiveAuthInterceptor { override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { // We missed server grace period or it's not setup, see if we remember locally password - if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD - && errCode == null - && reAuthHelper.data != null) { + if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && + errCode == null && + reAuthHelper.data != null) { promise.resume( UserPasswordAuth( session = flowResponse.session, diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailAction.kt index b466f204ec..26f0e56f23 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailAction.kt @@ -21,5 +21,5 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class HomeDetailAction : VectorViewModelAction { data class SwitchTab(val tab: HomeTab) : HomeDetailAction() object MarkAllRoomsRead : HomeDetailAction() - data class StartCallWithPhoneNumber(val phoneNumber: String): HomeDetailAction() + data class StartCallWithPhoneNumber(val phoneNumber: String) : HomeDetailAction() } 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 627f4b4581..24677cf940 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 @@ -155,7 +155,7 @@ class HomeDetailFragment @Inject constructor( viewModel.observeViewEvents { viewEvent -> when (viewEvent) { - HomeDetailViewEvents.CallStarted -> dismissLoadingDialog() + HomeDetailViewEvents.CallStarted -> handleCallStarted() is HomeDetailViewEvents.FailToCall -> showFailure(viewEvent.failure) HomeDetailViewEvents.Loading -> showLoadingDialog() } @@ -190,10 +190,16 @@ class HomeDetailFragment @Inject constructor( sharedCallActionViewModel .liveKnownCalls - .observe(viewLifecycleOwner, { + .observe(viewLifecycleOwner) { currentCallsViewPresenter.updateCall(callManager.getCurrentCall(), callManager.getCalls()) invalidateOptionsMenu() - }) + } + } + + private fun handleCallStarted() { + dismissLoadingDialog() + val fragmentTag = HomeTab.DialPad.toFragmentTag() + (childFragmentManager.findFragmentByTag(fragmentTag) as? DialPadFragment)?.clear() } override fun onDestroyView() { @@ -370,8 +376,10 @@ class HomeDetailFragment @Inject constructor( invalidateOptionsMenu() } + private fun HomeTab.toFragmentTag() = "FRAGMENT_TAG_$this" + private fun updateSelectedFragment(tab: HomeTab) { - val fragmentTag = "FRAGMENT_TAG_$tab" + val fragmentTag = tab.toFragmentTag() val fragmentToShow = childFragmentManager.findFragmentByTag(fragmentTag) childFragmentManager.commitTransaction { childFragmentManager.fragments diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 460975c2c2..494a414832 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -63,8 +63,8 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho private val callManager: WebRtcCallManager, private val directRoomHelper: DirectRoomHelper, private val appStateHandler: AppStateHandler, - private val autoAcceptInvites: AutoAcceptInvites) - : VectorViewModel(initialState), + private val autoAcceptInvites: AutoAcceptInvites) : + VectorViewModel(initialState), CallProtocolsChecker.Listener { @AssistedFactory diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt index 9ff865b9d1..3accc24740 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt @@ -30,13 +30,11 @@ import im.vector.app.core.extensions.replaceChildFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentHomeDrawerBinding -// import im.vector.app.features.grouplist.GroupListFragment import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.spaces.SpaceListFragment import im.vector.app.features.usercode.UserCodeActivity import im.vector.app.features.workers.signout.SignOutUiWorker - import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt b/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt index 2de36f2f5e..47cfd1c28f 100644 --- a/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt @@ -23,7 +23,6 @@ import android.view.View import android.view.ViewGroup import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentLoadingBinding - import javax.inject.Inject class LoadingFragment @Inject constructor() : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt index fc204a0c56..ee7edc021d 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt @@ -78,7 +78,6 @@ class ShortcutCreator @Inject constructor( .setLongLived(true) .setRank(rank) .setCategories(categories) - .build() } diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 988b4fbabe..b88fe141ec 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -25,8 +25,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModelAction @@ -58,8 +58,8 @@ data class DeviceDetectionInfo( class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted initialState: UnknownDevicesState, session: Session, - private val vectorPreferences: VectorPreferences) - : VectorViewModel(initialState) { + private val vectorPreferences: VectorPreferences) : + VectorViewModel(initialState) { sealed class Action : VectorViewModelAction { data class IgnoreDevice(val deviceIds: List) : Action() diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index ac983a9f0c..0ee7152cbb 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -57,8 +57,8 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia session: Session, private val vectorPreferences: VectorPreferences, appStateHandler: AppStateHandler, - private val autoAcceptInvites: AutoAcceptInvites) - : VectorViewModel(initialState) { + private val autoAcceptInvites: AutoAcceptInvites) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -177,12 +177,12 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia CountInfo( homeCount = counts, otherCount = RoomAggregateNotificationCount( - notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) - + (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) - + spaceInviteCount, - highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) - + (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) - + spaceInviteCount + notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) + + (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount, + highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) + + (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount ) ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt index d66f3848a5..47a8256628 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt @@ -28,7 +28,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentBreadcrumbsBinding import im.vector.app.features.home.room.detail.RoomDetailSharedAction import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel - import javax.inject.Inject class BreadcrumbsFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt index fd912a4953..52996c74de 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsItem.kt @@ -27,6 +27,7 @@ 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.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.list.UnreadCounterBadgeView import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt index d3825de4ef..39004f4ed4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt @@ -20,8 +20,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -33,8 +33,8 @@ import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.rx.rx class BreadcrumbsViewModel @AssistedInject constructor(@Assisted initialState: BreadcrumbsViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 8e6343519a..d4430730d7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -36,6 +36,7 @@ import im.vector.app.features.autocomplete.group.AutocompleteGroupPresenter import im.vector.app.features.autocomplete.member.AutocompleteMemberPresenter import im.vector.app.features.autocomplete.room.AutocompleteRoomPresenter import im.vector.app.features.command.Command +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan import im.vector.app.features.themes.ThemeUtils diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/ChatEffectManager.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/ChatEffectManager.kt index 24151c5c10..f95baae36b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/ChatEffectManager.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/ChatEffectManager.kt @@ -105,8 +105,8 @@ class ChatEffectManager @Inject constructor() { } private fun hasAlreadyPlayed(event: TimelineEvent): Boolean { - return alreadyPlayed.contains(event.eventId) - || (event.root.unsignedData?.transactionId?.let { alreadyPlayed.contains(it) } ?: false) + return alreadyPlayed.contains(event.eventId) || + (event.root.unsignedData?.transactionId?.let { alreadyPlayed.contains(it) } ?: false) } private fun findEffect(content: MessageContent, event: TimelineEvent): ChatEffect? { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index 9bb82cdc27..9c5f436728 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -30,10 +30,7 @@ import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.util.MatrixItem sealed class RoomDetailAction : VectorViewModelAction { - data class UserIsTyping(val isTyping: Boolean) : RoomDetailAction() - data class SaveDraft(val draft: String) : RoomDetailAction() data class SendSticker(val stickerContent: MessageStickerContent) : RoomDetailAction() - data class SendMessage(val text: CharSequence, val autoMarkdown: Boolean) : RoomDetailAction() data class SendMedia(val attachments: List, val compressBeforeSending: Boolean) : RoomDetailAction() data class TimelineEventTurnsVisible(val event: TimelineEvent) : RoomDetailAction() data class TimelineEventTurnsInvisible(val event: TimelineEvent) : RoomDetailAction() @@ -52,11 +49,6 @@ sealed class RoomDetailAction : VectorViewModelAction { object EnterTrackingUnreadMessagesState : RoomDetailAction() object ExitTrackingUnreadMessagesState : RoomDetailAction() - data class EnterEditMode(val eventId: String, val text: String) : RoomDetailAction() - data class EnterQuoteMode(val eventId: String, val text: String) : RoomDetailAction() - data class EnterReplyMode(val eventId: String, val text: String) : RoomDetailAction() - data class EnterRegularMode(val text: String, val fromSharing: Boolean) : RoomDetailAction() - data class ResendMessage(val eventId: String) : RoomDetailAction() data class RemoveFailedEcho(val eventId: String) : RoomDetailAction() data class CancelSend(val eventId: String, val force: Boolean) : RoomDetailAction() @@ -75,7 +67,7 @@ sealed class RoomDetailAction : VectorViewModelAction { object ResendAll : RoomDetailAction() data class StartCall(val isVideo: Boolean) : RoomDetailAction() - data class AcceptCall(val callId: String): RoomDetailAction() + data class AcceptCall(val callId: String) : RoomDetailAction() object EndCall : RoomDetailAction() data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction() @@ -91,13 +83,13 @@ sealed class RoomDetailAction : VectorViewModelAction { data class AddJitsiWidget(val withVideo: Boolean) : RoomDetailAction() data class RemoveWidget(val widgetId: String) : RoomDetailAction() - object JoinJitsiCall: RoomDetailAction() - object LeaveJitsiCall: RoomDetailAction() + object JoinJitsiCall : RoomDetailAction() + object LeaveJitsiCall : RoomDetailAction() data class EnsureNativeWidgetAllowed(val widget: Widget, val userJustAccepted: Boolean, val grantedEvents: RoomDetailViewEvents) : RoomDetailAction() - data class UpdateJoinJitsiCallStatus(val conferenceEvent: ConferenceEvent): RoomDetailAction() + data class UpdateJoinJitsiCallStatus(val conferenceEvent: ConferenceEvent) : RoomDetailAction() data class OpenOrCreateDm(val userId: String) : RoomDetailAction() data class JumpToReadReceipt(val userId: String) : RoomDetailAction() @@ -115,7 +107,7 @@ sealed class RoomDetailAction : VectorViewModelAction { // Failed messages object RemoveAllFailedMessages : RoomDetailAction() - data class RoomUpgradeSuccess(val replacementRoomId: String): RoomDetailAction() + data class RoomUpgradeSuccess(val replacementRoomId: String) : RoomDetailAction() // Voice Message object StartRecordingVoiceMessage : RoomDetailAction() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 25428bbfbf..76c3816ce6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -20,10 +20,12 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.widget.Toast -import com.google.android.material.appbar.MaterialToolbar import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager import com.airbnb.mvrx.viewModel +import com.google.android.material.appbar.MaterialToolbar import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.hideKeyboard @@ -32,25 +34,44 @@ import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityRoomDetailBinding import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment +import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.navigation.Navigator import im.vector.app.features.room.RequireActiveMembershipAction import im.vector.app.features.room.RequireActiveMembershipViewEvents import im.vector.app.features.room.RequireActiveMembershipViewModel import im.vector.app.features.room.RequireActiveMembershipViewState import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState - import javax.inject.Inject class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable, RequireActiveMembershipViewModel.Factory, - RoomWidgetPermissionViewModel.Factory { + RoomWidgetPermissionViewModel.Factory, + MatrixToBottomSheet.InteractionListener { override fun getBinding(): ActivityRoomDetailBinding { return ActivityRoomDetailBinding.inflate(layoutInflater) } + private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() { + + override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { + if (f is MatrixToBottomSheet) { + f.interactionListener = this@RoomDetailActivity + } + super.onFragmentResumed(fm, f) + } + + override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { + if (f is MatrixToBottomSheet) { + f.interactionListener = null + } + super.onFragmentPaused(fm, f) + } + } + override fun getCoordinatorLayout() = views.coordinatorLayout private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel @@ -79,6 +100,7 @@ class RoomDetailActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) waitingView = views.waitingView.waitingView val roomDetailArgs: RoomDetailArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) { RoomDetailArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!) @@ -130,6 +152,7 @@ class RoomDetailActivity : } override fun onDestroy() { + supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) views.drawerLayout.removeDrawerListener(drawerListener) super.onDestroy() } @@ -182,4 +205,12 @@ class RoomDetailActivity : } } } + + override fun mxToBottomSheetNavigateToRoom(roomId: String) { + navigator.openRoom(this, roomId) + } + + override fun mxToBottomSheetSwitchToSpace(spaceId: String) { + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index c6eda584ad..b3fe6fcbf4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -133,7 +133,12 @@ import im.vector.app.features.command.Command import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.home.room.detail.composer.SendMode +import im.vector.app.features.home.room.detail.composer.TextComposerAction import im.vector.app.features.home.room.detail.composer.TextComposerView +import im.vector.app.features.home.room.detail.composer.TextComposerViewEvents +import im.vector.app.features.home.room.detail.composer.TextComposerViewModel +import im.vector.app.features.home.room.detail.composer.TextComposerViewState import im.vector.app.features.home.room.detail.composer.VoiceMessageRecorderView import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet import im.vector.app.features.home.room.detail.timeline.TimelineEventController @@ -187,7 +192,6 @@ import nl.dionsegijn.konfetti.models.Shape import nl.dionsegijn.konfetti.models.Size import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.commonmark.parser.Parser -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.events.model.toModel @@ -235,6 +239,7 @@ class RoomDetailFragment @Inject constructor( private val permalinkHandler: PermalinkHandler, private val notificationDrawerManager: NotificationDrawerManager, val roomDetailViewModelFactory: RoomDetailViewModel.Factory, + val textComposerViewModelFactory: TextComposerViewModel.Factory, private val eventHtmlRenderer: EventHtmlRenderer, private val vectorPreferences: VectorPreferences, private val colorProvider: ColorProvider, @@ -287,6 +292,7 @@ class RoomDetailFragment @Inject constructor( autoCompleterFactory.create(roomDetailArgs.roomId) } private val roomDetailViewModel: RoomDetailViewModel by fragmentViewModel() + private val textComposerViewModel: TextComposerViewModel by fragmentViewModel() private val debouncer = Debouncer(createUIHandler()) private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback @@ -375,11 +381,11 @@ class RoomDetailFragment @Inject constructor( invalidateOptionsMenu() } - roomDetailViewModel.selectSubscribe(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ -> + roomDetailViewModel.selectSubscribe(this, RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ -> updateJumpToReadMarkerViewVisibility() } - roomDetailViewModel.selectSubscribe(RoomDetailViewState::sendMode, RoomDetailViewState::canSendMessage) { mode, canSend -> + textComposerViewModel.selectSubscribe(this, TextComposerViewState::sendMode, TextComposerViewState::canSendMessage) { mode, canSend -> if (!canSend) { return@selectSubscribe } @@ -392,6 +398,7 @@ class RoomDetailFragment @Inject constructor( } roomDetailViewModel.selectSubscribe( + this, RoomDetailViewState::syncState, RoomDetailViewState::incrementalSyncStatus, RoomDetailViewState::pushCounter @@ -404,6 +411,17 @@ class RoomDetailFragment @Inject constructor( ) } + textComposerViewModel.observeViewEvents { + when (it) { + is TextComposerViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it) + is TextComposerViewEvents.SendMessageResult -> renderSendMessageResult(it) + is TextComposerViewEvents.ShowMessage -> showSnackWithMessage(it.message) + is TextComposerViewEvents.ShowRoomUpgradeDialog -> handleShowRoomUpgradeDialog(it) + is TextComposerViewEvents.AnimateSendButtonVisibility -> handleSendButtonVisibilityChanged(it) + is TextComposerViewEvents.OpenRoomMemberProfile -> openRoomMemberProfile(it.userId) + }.exhaustive + } + roomDetailViewModel.observeViewEvents { when (it) { is RoomDetailViewEvents.Failure -> { @@ -418,8 +436,6 @@ class RoomDetailFragment @Inject constructor( is RoomDetailViewEvents.ShowMessage -> showSnackWithMessage(it.message) is RoomDetailViewEvents.NavigateToEvent -> navigateToEvent(it) is RoomDetailViewEvents.DownloadFileState -> handleDownloadFileState(it) - is RoomDetailViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it) - is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it) is RoomDetailViewEvents.ShowE2EErrorMessage -> displayE2eError(it.withHeldCode) RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager() is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it) @@ -444,7 +460,6 @@ class RoomDetailFragment @Inject constructor( RoomDetailViewEvents.StopChatEffects -> handleStopChatEffects() is RoomDetailViewEvents.DisplayAndAcceptCall -> acceptIncomingCall(it) RoomDetailViewEvents.RoomReplacementStarted -> handleRoomReplacement() - is RoomDetailViewEvents.ShowRoomUpgradeDialog -> handleShowRoomUpgradeDialog(it) }.exhaustive } @@ -454,6 +469,20 @@ class RoomDetailFragment @Inject constructor( } } + private fun handleSendButtonVisibilityChanged(event: TextComposerViewEvents.AnimateSendButtonVisibility) { + if (event.isVisible) { + views.voiceMessageRecorderView.isVisible = false + views.composerLayout.views.sendButton.alpha = 0f + views.composerLayout.views.sendButton.isVisible = true + views.composerLayout.views.sendButton.animate().alpha(1f).setDuration(150).start() + } else { + views.composerLayout.views.sendButton.isInvisible = true + views.voiceMessageRecorderView.alpha = 0f + views.voiceMessageRecorderView.isVisible = true + views.voiceMessageRecorderView.animate().alpha(1f).setDuration(150).start() + } + } + private fun setupRemoveJitsiWidgetView() { views.removeJitsiWidgetView.onCompleteSliding = { withState(roomDetailViewModel) { @@ -495,7 +524,7 @@ class RoomDetailFragment @Inject constructor( JoinReplacementRoomBottomSheet().show(childFragmentManager, tag) } - private fun handleShowRoomUpgradeDialog(roomDetailViewEvents: RoomDetailViewEvents.ShowRoomUpgradeDialog) { + private fun handleShowRoomUpgradeDialog(roomDetailViewEvents: TextComposerViewEvents.ShowRoomUpgradeDialog) { val tag = MigrateRoomBottomSheet::javaClass.name MigrateRoomBottomSheet.newInstance(roomDetailArgs.roomId, roomDetailViewEvents.newVersion) .show(parentFragmentManager, tag) @@ -656,8 +685,8 @@ class RoomDetailFragment @Inject constructor( views.voiceMessageRecorderView.callback = object : VoiceMessageRecorderView.Callback { override fun onVoiceRecordingStarted(): Boolean { return if (checkPermissions(PERMISSIONS_FOR_VOICE_MESSAGE, requireActivity(), permissionVoiceMessageLauncher)) { - views.composerLayout.isInvisible = true roomDetailViewModel.handle(RoomDetailAction.StartRecordingVoiceMessage) + textComposerViewModel.handle(TextComposerAction.OnVoiceRecordingStateChanged(true)) vibrate(requireContext()) true } else { @@ -667,8 +696,8 @@ class RoomDetailFragment @Inject constructor( } override fun onVoiceRecordingEnded(isCancelled: Boolean) { - views.composerLayout.isInvisible = false roomDetailViewModel.handle(RoomDetailAction.EndRecordingVoiceMessage(isCancelled)) + textComposerViewModel.handle(TextComposerAction.OnVoiceRecordingStateChanged(false)) } override fun onVoiceRecordingPlaybackModeOn() { @@ -753,8 +782,8 @@ class RoomDetailFragment @Inject constructor( .show() } - private fun handleJoinedToAnotherRoom(action: RoomDetailViewEvents.JoinRoomCommandSuccess) { - updateComposerText("") + private fun handleJoinedToAnotherRoom(action: TextComposerViewEvents.JoinRoomCommandSuccess) { + views.composerLayout.setTextIfDifferent("") lockSendButton = false navigator.openRoom(vectorBaseActivity, action.roomId) } @@ -762,7 +791,7 @@ class RoomDetailFragment @Inject constructor( private fun handleShareData() { when (val sharedData = roomDetailArgs.sharedData) { is SharedData.Text -> { - roomDetailViewModel.handle(RoomDetailAction.EnterRegularMode(sharedData.text, fromSharing = true)) + textComposerViewModel.handle(TextComposerAction.EnterRegularMode(sharedData.text, fromSharing = true)) } is SharedData.Attachments -> { // open share edition @@ -980,10 +1009,7 @@ class RoomDetailFragment @Inject constructor( private fun renderRegularMode(text: String) { autoCompleter.exitSpecialMode() views.composerLayout.collapse() - - views.voiceMessageRecorderView.isVisible = text.isBlank() - - updateComposerText(text) + views.composerLayout.setTextIfDifferent(text) views.composerLayout.views.sendButton.contentDescription = getString(R.string.send) } @@ -1022,7 +1048,7 @@ class RoomDetailFragment @Inject constructor( false } - updateComposerText(defaultContent) + views.composerLayout.setTextIfDifferent(defaultContent) views.composerLayout.views.composerRelatedMessageActionIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), iconRes)) views.composerLayout.views.sendButton.contentDescription = getString(descriptionRes) @@ -1034,21 +1060,11 @@ class RoomDetailFragment @Inject constructor( // need to do it here also when not using quick reply focusComposerAndShowKeyboard() views.composerLayout.views.composerRelatedMessageImage.isVisible = isImageVisible - views.voiceMessageRecorderView.isVisible = false } } focusComposerAndShowKeyboard() } - private fun updateComposerText(text: String) { - // Do not update if this is the same text to avoid the cursor to move - if (text != views.composerLayout.text.toString()) { - // Ignore update to avoid saving a draft - views.composerLayout.views.composerEditText.setText(text) - views.composerLayout.views.composerEditText.setSelection(views.composerLayout.text?.length ?: 0) - } - } - override fun onResume() { super.onResume() notificationDrawerManager.setCurrentRoom(roomDetailArgs.roomId) @@ -1077,7 +1093,7 @@ class RoomDetailFragment @Inject constructor( notificationDrawerManager.setCurrentRoom(null) - roomDetailViewModel.handle(RoomDetailAction.SaveDraft(views.composerLayout.text.toString())) + textComposerViewModel.handle(TextComposerAction.SaveDraft(views.composerLayout.text.toString())) // We should improve the UX to support going into playback mode when paused and delete the media when the view is destroyed. roomDetailViewModel.handle(RoomDetailAction.EndAllVoiceActions) @@ -1196,12 +1212,12 @@ class RoomDetailFragment @Inject constructor( override fun performQuickReplyOnHolder(model: EpoxyModel<*>) { (model as? AbsMessageItem)?.attributes?.informationData?.let { val eventId = it.eventId - roomDetailViewModel.handle(RoomDetailAction.EnterReplyMode(eventId, views.composerLayout.text.toString())) + textComposerViewModel.handle(TextComposerAction.EnterReplyMode(eventId, views.composerLayout.text.toString())) } } override fun canSwipeModel(model: EpoxyModel<*>): Boolean { - val canSendMessage = withState(roomDetailViewModel) { + val canSendMessage = withState(textComposerViewModel) { it.canSendMessage } if (!canSendMessage) { @@ -1279,10 +1295,10 @@ class RoomDetailFragment @Inject constructor( true } // Add external keyboard functionality (to send messages) - else if (null != keyEvent - && !keyEvent.isShiftPressed - && keyEvent.keyCode == KeyEvent.KEYCODE_ENTER - && resources.configuration.keyboard != Configuration.KEYBOARD_NOKEYS) { + else if (null != keyEvent && + !keyEvent.isShiftPressed && + keyEvent.keyCode == KeyEvent.KEYCODE_ENTER && + resources.configuration.keyboard != Configuration.KEYBOARD_NOKEYS) { sendTextMessage(v.text) true } else false @@ -1303,22 +1319,15 @@ class RoomDetailFragment @Inject constructor( } override fun onCloseRelatedMessage() { - roomDetailViewModel.handle(RoomDetailAction.EnterRegularMode(views.composerLayout.text.toString(), false)) + textComposerViewModel.handle(TextComposerAction.EnterRegularMode(views.composerLayout.text.toString(), false)) } override fun onRichContentSelected(contentUri: Uri): Boolean { return sendUri(contentUri) } - override fun onTextBlankStateChanged(isBlank: Boolean) { - if (!views.composerLayout.views.sendButton.isVisible) { - // Animate alpha to prevent overlapping with the animation of the send button - views.voiceMessageRecorderView.alpha = 0f - views.voiceMessageRecorderView.isVisible = true - views.voiceMessageRecorderView.animate().alpha(1f).setDuration(300).start() - } else { - views.voiceMessageRecorderView.isVisible = false - } + override fun onTextChanged(text: CharSequence) { + textComposerViewModel.handle(TextComposerAction.OnTextChanged(text)) } } } @@ -1332,7 +1341,7 @@ class RoomDetailFragment @Inject constructor( // We collapse ASAP, if not there will be a slight annoying delay views.composerLayout.collapse(true) lockSendButton = true - roomDetailViewModel.handle(RoomDetailAction.SendMessage(text, vectorPreferences.isMarkdownEnabled())) + textComposerViewModel.handle(TextComposerAction.SendMessage(text, vectorPreferences.isMarkdownEnabled())) emojiPopup.dismiss() } } @@ -1344,7 +1353,7 @@ class RoomDetailFragment @Inject constructor( .map { it.isNotEmpty() } .subscribe { Timber.d("Typing: User is typing: $it") - roomDetailViewModel.handle(RoomDetailAction.UserIsTyping(it)) + textComposerViewModel.handle(TextComposerAction.UserIsTyping(it)) } .disposeOnDestroyView() @@ -1364,56 +1373,56 @@ class RoomDetailFragment @Inject constructor( return isHandled } - override fun invalidate() = withState(roomDetailViewModel) { state -> + override fun invalidate() = withState(roomDetailViewModel, textComposerViewModel) { mainState, textComposerState -> invalidateOptionsMenu() - val summary = state.asyncRoomSummary() - renderToolbar(summary, state.typingMessage) - views.removeJitsiWidgetView.render(state) - if (state.hasFailedSending) { + val summary = mainState.asyncRoomSummary() + renderToolbar(summary, mainState.formattedTypingUsers) + views.removeJitsiWidgetView.render(mainState) + if (mainState.hasFailedSending) { lazyLoadedViews.failedMessagesWarningView(inflateIfNeeded = true, createFailedMessagesWarningCallback())?.isVisible = true } else { lazyLoadedViews.failedMessagesWarningView(inflateIfNeeded = false)?.isVisible = false } - val inviter = state.asyncInviter() + val inviter = mainState.asyncInviter() if (summary?.membership == Membership.JOIN) { views.jumpToBottomView.count = summary.notificationCount views.jumpToBottomView.drawBadge = summary.hasUnreadMessages - timelineEventController.update(state) + timelineEventController.update(mainState) lazyLoadedViews.inviteView(false)?.isVisible = false - if (state.tombstoneEvent == null) { - if (state.canSendMessage) { - if (!views.voiceMessageRecorderView.isActive()) { - views.composerLayout.isVisible = true - views.voiceMessageRecorderView.isVisible = views.composerLayout.text?.isBlank().orFalse() - views.composerLayout.setRoomEncrypted(summary.isEncrypted) - views.notificationAreaView.render(NotificationAreaView.State.Hidden) - views.composerLayout.alwaysShowSendButton = false - } + if (mainState.tombstoneEvent == null) { + views.composerLayout.isInvisible = !textComposerState.isComposerVisible + views.voiceMessageRecorderView.isVisible = !textComposerState.isSendButtonVisible + views.composerLayout.views.sendButton.isInvisible = !textComposerState.isSendButtonVisible + views.composerLayout.setRoomEncrypted(summary.isEncrypted) + // views.composerLayout.alwaysShowSendButton = false + if (textComposerState.canSendMessage) { + views.notificationAreaView.render(NotificationAreaView.State.Hidden) } else { - views.composerLayout.isVisible = false - views.voiceMessageRecorderView.isVisible = false views.notificationAreaView.render(NotificationAreaView.State.NoPermissionToPost) } } else { - views.composerLayout.isVisible = false - views.voiceMessageRecorderView.isVisible = false - views.notificationAreaView.render(NotificationAreaView.State.Tombstone(state.tombstoneEvent)) + views.hideComposerViews() + views.notificationAreaView.render(NotificationAreaView.State.Tombstone(mainState.tombstoneEvent)) } } else if (summary?.membership == Membership.INVITE && inviter != null) { - views.composerLayout.isVisible = false - views.voiceMessageRecorderView.isVisible = false + views.hideComposerViews() lazyLoadedViews.inviteView(true)?.apply { callback = this@RoomDetailFragment isVisible = true - render(inviter, VectorInviteView.Mode.LARGE, state.changeMembershipState) + render(inviter, VectorInviteView.Mode.LARGE, mainState.changeMembershipState) setOnClickListener { } } Unit - } else if (state.asyncInviter.complete) { + } else if (mainState.asyncInviter.complete) { vectorBaseActivity.finish() } } + private fun FragmentRoomDetailBinding.hideComposerViews() { + composerLayout.isVisible = false + voiceMessageRecorderView.isVisible = false + } + private fun renderToolbar(roomSummary: RoomSummary?, typingMessage: String?) { if (roomSummary == null) { views.roomToolbarContentView.isClickable = false @@ -1442,24 +1451,24 @@ class RoomDetailFragment @Inject constructor( } } - private fun renderSendMessageResult(sendMessageResult: RoomDetailViewEvents.SendMessageResult) { + private fun renderSendMessageResult(sendMessageResult: TextComposerViewEvents.SendMessageResult) { when (sendMessageResult) { - is RoomDetailViewEvents.SlashCommandHandled -> { + is TextComposerViewEvents.SlashCommandHandled -> { sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) } } - is RoomDetailViewEvents.SlashCommandError -> { + is TextComposerViewEvents.SlashCommandError -> { displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command)) } - is RoomDetailViewEvents.SlashCommandUnknown -> { + is TextComposerViewEvents.SlashCommandUnknown -> { displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command)) } - is RoomDetailViewEvents.SlashCommandResultOk -> { - updateComposerText("") + is TextComposerViewEvents.SlashCommandResultOk -> { + views.composerLayout.setTextIfDifferent("") } - is RoomDetailViewEvents.SlashCommandResultError -> { + is TextComposerViewEvents.SlashCommandResultError -> { displayCommandError(errorFormatter.toHumanReadable(sendMessageResult.throwable)) } - is RoomDetailViewEvents.SlashCommandNotImplemented -> { + is TextComposerViewEvents.SlashCommandNotImplemented -> { displayCommandError(getString(R.string.not_implemented)) } } // .exhaustive @@ -1865,8 +1874,8 @@ class RoomDetailFragment @Inject constructor( } private fun onSaveActionClicked(action: EventSharedAction.Save) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q - && !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, requireActivity(), saveActionActivityResultLauncher)) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && + !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, requireActivity(), saveActionActivityResultLauncher)) { sharedActionViewModel.pendingAction = action return } @@ -1938,17 +1947,17 @@ class RoomDetailFragment @Inject constructor( } is EventSharedAction.Edit -> { if (!views.voiceMessageRecorderView.isActive()) { - roomDetailViewModel.handle(RoomDetailAction.EnterEditMode(action.eventId, views.composerLayout.text.toString())) + textComposerViewModel.handle(TextComposerAction.EnterEditMode(action.eventId, views.composerLayout.text.toString())) } else { requireActivity().toast(R.string.error_voice_message_cannot_reply_or_edit) } } is EventSharedAction.Quote -> { - roomDetailViewModel.handle(RoomDetailAction.EnterQuoteMode(action.eventId, views.composerLayout.text.toString())) + textComposerViewModel.handle(TextComposerAction.EnterQuoteMode(action.eventId, views.composerLayout.text.toString())) } is EventSharedAction.Reply -> { if (!views.voiceMessageRecorderView.isActive()) { - roomDetailViewModel.handle(RoomDetailAction.EnterReplyMode(action.eventId, views.composerLayout.text.toString())) + textComposerViewModel.handle(TextComposerAction.EnterReplyMode(action.eventId, views.composerLayout.text.toString())) } else { requireActivity().toast(R.string.error_voice_message_cannot_reply_or_edit) } @@ -2018,8 +2027,8 @@ class RoomDetailFragment @Inject constructor( private fun insertUserDisplayNameInTextEditor(userId: String) { val startToCompose = views.composerLayout.text.isNullOrBlank() - if (startToCompose - && userId == session.myUserId) { + if (startToCompose && + userId == session.myUserId) { // Empty composer, current user: start an emote views.composerLayout.views.composerEditText.setText(Command.EMOTE.command + " ") views.composerLayout.views.composerEditText.setSelection(Command.EMOTE.length) @@ -2160,7 +2169,7 @@ class RoomDetailFragment @Inject constructor( override fun onContactAttachmentReady(contactAttachment: ContactAttachment) { super.onContactAttachmentReady(contactAttachment) val formattedContact = contactAttachment.toHumanReadable() - roomDetailViewModel.handle(RoomDetailAction.SendMessage(formattedContact, false)) + textComposerViewModel.handle(TextComposerAction.SendMessage(formattedContact, false)) } private fun onViewWidgetsClicked() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 2802ee2f83..2e7f2bfd63 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -18,10 +18,8 @@ package im.vector.app.features.home.room.detail import android.net.Uri import android.view.View -import androidx.annotation.StringRes import im.vector.app.core.platform.VectorViewEvents import im.vector.app.features.call.webrtc.WebRtcCall -import im.vector.app.features.command.Command import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode @@ -66,9 +64,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents { val mimeType: String? ) : RoomDetailViewEvents() - abstract class SendMessageResult : RoomDetailViewEvents() - - data class DisplayAndAcceptCall(val call: WebRtcCall): RoomDetailViewEvents() + data class DisplayAndAcceptCall(val call: WebRtcCall) : RoomDetailViewEvents() object DisplayPromptForIntegrationManager : RoomDetailViewEvents() @@ -82,19 +78,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents { val domain: String, val grantedEvents: RoomDetailViewEvents) : RoomDetailViewEvents() - object MessageSent : SendMessageResult() - data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult() - class SlashCommandError(val command: Command) : SendMessageResult() - class SlashCommandUnknown(val command: String) : SendMessageResult() - data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() - object SlashCommandResultOk : SendMessageResult() - class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() - - // TODO Remove - object SlashCommandNotImplemented : SendMessageResult() - data class StartChatEffect(val type: ChatEffect) : RoomDetailViewEvents() object StopChatEffects : RoomDetailViewEvents() object RoomReplacementStarted : RoomDetailViewEvents() - data class ShowRoomUpgradeDialog(val newVersion: String, val isPublic: Boolean): RoomDetailViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index cacf9b8902..bd11ec6718 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -44,13 +44,10 @@ import im.vector.app.features.call.conference.JitsiActiveConferenceHolder import im.vector.app.features.call.conference.JitsiService import im.vector.app.features.call.lookup.CallProtocolsChecker import im.vector.app.features.call.webrtc.WebRtcCallManager -import im.vector.app.features.command.CommandParser -import im.vector.app.features.command.ParsedCommand import im.vector.app.features.createdirect.DirectRoomHelper import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy import im.vector.app.features.crypto.verification.SupportedVerificationMethodsProvider import im.vector.app.features.home.room.detail.composer.VoiceMessageHelper -import im.vector.app.features.home.room.detail.composer.rainbow.RainbowGenerator import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandler import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever @@ -67,9 +64,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.commonmark.parser.Parser -import org.commonmark.renderer.html.HtmlRenderer -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.QueryStringValue @@ -86,22 +80,14 @@ import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.api.session.room.model.message.OptionItem import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.read.ReadService -import org.matrix.android.sdk.api.session.room.send.UserDraft import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent -import org.matrix.android.sdk.api.session.room.timeline.getRelationContent -import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent -import org.matrix.android.sdk.api.session.space.CreateSpaceParams import org.matrix.android.sdk.api.session.widgets.model.WidgetType import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode @@ -117,7 +103,6 @@ class RoomDetailViewModel @AssistedInject constructor( private val vectorPreferences: VectorPreferences, private val vectorDataStore: VectorDataStore, private val stringProvider: StringProvider, - private val rainbowGenerator: RainbowGenerator, private val session: Session, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, private val stickerPickerActionHandler: StickerPickerActionHandler, @@ -181,7 +166,6 @@ class RoomDetailViewModel @AssistedInject constructor( observeSyncState() observeDataStore() observeEventDisplayedActions() - loadDraftIfAny() observeUnreadState() observeMyRoomMember() observeActiveRoomWidgets() @@ -235,13 +219,11 @@ class RoomDetailViewModel @AssistedInject constructor( private fun observePowerLevel() { PowerLevelsObservableFactory(room).createObservable() .subscribe { - val canSendMessage = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE) val canInvite = PowerLevelsHelper(it).isUserAbleToInvite(session.myUserId) val isAllowedToManageWidgets = session.widgetService().hasPermissionsToHandleWidgets(room.roomId) val isAllowedToStartWebRTCCall = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.CALL_INVITE) setState { copy( - canSendMessage = canSendMessage, canInvite = canInvite, isAllowedToManageWidgets = isAllowedToManageWidgets, isAllowedToStartWebRTCCall = isAllowedToStartWebRTCCall @@ -300,10 +282,7 @@ class RoomDetailViewModel @AssistedInject constructor( override fun handle(action: RoomDetailAction) { when (action) { - is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action) is RoomDetailAction.ComposerFocusChange -> handleComposerFocusChange(action) - is RoomDetailAction.SaveDraft -> handleSaveDraft(action) - is RoomDetailAction.SendMessage -> handleSendMessage(action) is RoomDetailAction.SendMedia -> handleSendMedia(action) is RoomDetailAction.SendSticker -> handleSendSticker(action) is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action) @@ -315,10 +294,6 @@ class RoomDetailViewModel @AssistedInject constructor( is RoomDetailAction.RedactAction -> handleRedactEvent(action) is RoomDetailAction.UndoReaction -> handleUndoReact(action) is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action) - is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action) - is RoomDetailAction.EnterEditMode -> handleEditAction(action) - is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action) - is RoomDetailAction.EnterReplyMode -> handleReplyAction(action) is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action) is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action) is RoomDetailAction.JoinAndOpenReplacementRoom -> handleJoinAndOpenReplacementRoom() @@ -550,8 +525,8 @@ class RoomDetailViewModel @AssistedInject constructor( val widget = action.widget val domain = action.widget.widgetContent.data["domain"] as? String ?: "" val isAllowed = action.userJustAccepted || if (widget.type == WidgetType.Jitsi) { - widget.senderInfo?.userId == session.myUserId - || session.integrationManagerService().isNativeWidgetDomainAllowed( + widget.senderInfo?.userId == session.myUserId || + session.integrationManagerService().isNativeWidgetDomainAllowed( action.widget.type.preferred, domain ) @@ -590,70 +565,6 @@ class RoomDetailViewModel @AssistedInject constructor( return room.getRoomMember(userId) } - /** - * Convert a send mode to a draft and save the draft - */ - private fun handleSaveDraft(action: RoomDetailAction.SaveDraft) = withState { - session.coroutineScope.launch { - when { - it.sendMode is SendMode.REGULAR && !it.sendMode.fromSharing -> { - setState { copy(sendMode = it.sendMode.copy(action.draft)) } - room.saveDraft(UserDraft.REGULAR(action.draft)) - } - it.sendMode is SendMode.REPLY -> { - setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } - room.saveDraft(UserDraft.REPLY(it.sendMode.timelineEvent.root.eventId!!, action.draft)) - } - it.sendMode is SendMode.QUOTE -> { - setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } - room.saveDraft(UserDraft.QUOTE(it.sendMode.timelineEvent.root.eventId!!, action.draft)) - } - it.sendMode is SendMode.EDIT -> { - setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } - room.saveDraft(UserDraft.EDIT(it.sendMode.timelineEvent.root.eventId!!, action.draft)) - } - } - } - } - - private fun loadDraftIfAny() { - val currentDraft = room.getDraft() - setState { - copy( - // Create a sendMode from a draft and retrieve the TimelineEvent - sendMode = when (currentDraft) { - is UserDraft.REGULAR -> SendMode.REGULAR(currentDraft.text, false) - is UserDraft.QUOTE -> { - room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> - SendMode.QUOTE(timelineEvent, currentDraft.text) - } - } - is UserDraft.REPLY -> { - room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> - SendMode.REPLY(timelineEvent, currentDraft.text) - } - } - is UserDraft.EDIT -> { - room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> - SendMode.EDIT(timelineEvent, currentDraft.text) - } - } - else -> null - } ?: SendMode.REGULAR("", fromSharing = false) - ) - } - } - - private fun handleUserIsTyping(action: RoomDetailAction.UserIsTyping) { - if (vectorPreferences.sendTypingNotifs()) { - if (action.isTyping) { - room.userIsTyping() - } else { - room.userStopsTyping() - } - } - } - private fun handleComposerFocusChange(action: RoomDetailAction.ComposerFocusChange) { // Ensure outbound session keys if (OutboundSessionKeySharingStrategy.WhenTyping == BuildConfig.outboundSessionKeySharingStrategy && room.isEncrypted()) { @@ -766,417 +677,7 @@ class RoomDetailViewModel @AssistedInject constructor( } } -// PRIVATE METHODS ***************************************************************************** - - private fun handleSendMessage(action: RoomDetailAction.SendMessage) { - withState { state -> - when (state.sendMode) { - is SendMode.REGULAR -> { - when (val slashCommandResult = CommandParser.parseSplashCommand(action.text)) { - is ParsedCommand.ErrorNotACommand -> { - // Send the text message to the room - room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown) - _viewEvents.post(RoomDetailViewEvents.MessageSent) - popDraft() - } - is ParsedCommand.ErrorSyntax -> { - _viewEvents.post(RoomDetailViewEvents.SlashCommandError(slashCommandResult.command)) - } - is ParsedCommand.ErrorEmptySlashCommand -> { - _viewEvents.post(RoomDetailViewEvents.SlashCommandUnknown("/")) - } - is ParsedCommand.ErrorUnknownSlashCommand -> { - _viewEvents.post(RoomDetailViewEvents.SlashCommandUnknown(slashCommandResult.slashCommand)) - } - is ParsedCommand.SendPlainText -> { - // Send the text message to the room, without markdown - room.sendTextMessage(slashCommandResult.message, autoMarkdown = false) - _viewEvents.post(RoomDetailViewEvents.MessageSent) - popDraft() - } - is ParsedCommand.Invite -> { - handleInviteSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.Invite3Pid -> { - handleInvite3pidSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.SetUserPowerLevel -> { - handleSetUserPowerLevel(slashCommandResult) - popDraft() - } - is ParsedCommand.ClearScalarToken -> { - // TODO - _viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented) - } - is ParsedCommand.SetMarkdown -> { - vectorPreferences.setMarkdownEnabled(slashCommandResult.enable) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled( - if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) - popDraft() - } - is ParsedCommand.UnbanUser -> { - handleUnbanSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.BanUser -> { - handleBanSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.KickUser -> { - handleKickSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.JoinRoom -> { - handleJoinToAnotherRoomSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.PartRoom -> { - // TODO - _viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented) - } - is ParsedCommand.SendEmote -> { - room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendRainbow -> { - slashCommandResult.message.toString().let { - room.sendFormattedTextMessage(it, rainbowGenerator.generate(it)) - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendRainbowEmote -> { - slashCommandResult.message.toString().let { - room.sendFormattedTextMessage(it, rainbowGenerator.generate(it), MessageType.MSGTYPE_EMOTE) - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendSpoiler -> { - room.sendFormattedTextMessage( - "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})", - "${slashCommandResult.message}" - ) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendShrug -> { - val sequence = buildString { - append("¯\\_(ツ)_/¯") - if (slashCommandResult.message.isNotEmpty()) { - append(" ") - append(slashCommandResult.message) - } - } - room.sendTextMessage(sequence) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendChatEffect -> { - sendChatEffect(slashCommandResult) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.SendPoll -> { - room.sendPoll(slashCommandResult.question, slashCommandResult.options.mapIndexed { index, s -> OptionItem(s, "$index. $s") }) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.ChangeTopic -> { - handleChangeTopicSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.ChangeDisplayName -> { - handleChangeDisplayNameSlashCommand(slashCommandResult) - popDraft() - } - is ParsedCommand.DiscardSession -> { - if (room.isEncrypted()) { - session.cryptoService().discardOutboundSession(room.roomId) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } else { - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - _viewEvents.post( - RoomDetailViewEvents - .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled)) - ) - } - } - is ParsedCommand.CreateSpace -> { - viewModelScope.launch(Dispatchers.IO) { - try { - val params = CreateSpaceParams().apply { - name = slashCommandResult.name - invitedUserIds.addAll(slashCommandResult.invitees) - } - val spaceId = session.spaceService().createSpace(params) - session.spaceService().getSpace(spaceId) - ?.addChildren( - state.roomId, - null, - null, - true - ) - } catch (failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - } - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.AddToSpace -> { - viewModelScope.launch(Dispatchers.IO) { - try { - session.spaceService().getSpace(slashCommandResult.spaceId) - ?.addChildren( - room.roomId, - null, - null, - false - ) - } catch (failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - } - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.JoinSpace -> { - viewModelScope.launch(Dispatchers.IO) { - try { - session.spaceService().joinSpace(slashCommandResult.spaceIdOrAlias) - } catch (failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - } - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.LeaveRoom -> { - viewModelScope.launch(Dispatchers.IO) { - try { - session.getRoom(slashCommandResult.roomId)?.leave(null) - } catch (failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - } - } - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - is ParsedCommand.UpgradeRoom -> { - _viewEvents.post( - RoomDetailViewEvents.ShowRoomUpgradeDialog( - slashCommandResult.newVersion, - room.roomSummary()?.isPublic ?: false - ) - ) - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - popDraft() - } - }.exhaustive - } - is SendMode.EDIT -> { - // is original event a reply? - val inReplyTo = state.sendMode.timelineEvent.getRelationContent()?.inReplyTo?.eventId - if (inReplyTo != null) { - // TODO check if same content? - room.getTimeLineEvent(inReplyTo)?.let { - room.editReply(state.sendMode.timelineEvent, it, action.text.toString()) - } - } else { - val messageContent = state.sendMode.timelineEvent.getLastMessageContent() - val existingBody = messageContent?.body ?: "" - if (existingBody != action.text) { - room.editTextMessage(state.sendMode.timelineEvent, - messageContent?.msgType ?: MessageType.MSGTYPE_TEXT, - action.text, - action.autoMarkdown) - } else { - Timber.w("Same message content, do not send edition") - } - } - _viewEvents.post(RoomDetailViewEvents.MessageSent) - popDraft() - } - is SendMode.QUOTE -> { - val messageContent = state.sendMode.timelineEvent.getLastMessageContent() - val textMsg = messageContent?.body - - val finalText = legacyRiotQuoteText(textMsg, action.text.toString()) - - // TODO check for pills? - - // TODO Refactor this, just temporary for quotes - val parser = Parser.builder().build() - val document = parser.parse(finalText) - val renderer = HtmlRenderer.builder().build() - val htmlText = renderer.render(document) - if (finalText == htmlText) { - room.sendTextMessage(finalText) - } else { - room.sendFormattedTextMessage(finalText, htmlText) - } - _viewEvents.post(RoomDetailViewEvents.MessageSent) - popDraft() - } - is SendMode.REPLY -> { - state.sendMode.timelineEvent.let { - room.replyToMessage(it, action.text.toString(), action.autoMarkdown) - _viewEvents.post(RoomDetailViewEvents.MessageSent) - popDraft() - } - } - }.exhaustive - } - } - - private fun sendChatEffect(sendChatEffect: ParsedCommand.SendChatEffect) { - // If message is blank, convert to an emote, with default message - if (sendChatEffect.message.isBlank()) { - val defaultMessage = stringProvider.getString(when (sendChatEffect.chatEffect) { - ChatEffect.CONFETTI -> R.string.default_message_emote_confetti - ChatEffect.SNOWFALL -> R.string.default_message_emote_snow - }) - room.sendTextMessage(defaultMessage, MessageType.MSGTYPE_EMOTE) - } else { - room.sendTextMessage(sendChatEffect.message, sendChatEffect.chatEffect.toMessageType()) - } - } - - private fun popDraft() = withState { - if (it.sendMode is SendMode.REGULAR && it.sendMode.fromSharing) { - // If we were sharing, we want to get back our last value from draft - loadDraftIfAny() - } else { - // Otherwise we clear the composer and remove the draft from db - setState { copy(sendMode = SendMode.REGULAR("", false)) } - viewModelScope.launch { - room.deleteDraft() - } - } - } - - private fun handleJoinToAnotherRoomSlashCommand(command: ParsedCommand.JoinRoom) { - viewModelScope.launch { - try { - session.joinRoom(command.roomAlias, command.reason, emptyList()) - } catch (failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - return@launch - } - session.getRoomSummary(command.roomAlias) - ?.roomId - ?.let { - _viewEvents.post(RoomDetailViewEvents.JoinRoomCommandSuccess(it)) - } - } - } - - private fun legacyRiotQuoteText(quotedText: String?, myText: String): String { - val messageParagraphs = quotedText?.split("\n\n".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() - return buildString { - if (messageParagraphs != null) { - for (i in messageParagraphs.indices) { - if (messageParagraphs[i].isNotBlank()) { - append("> ") - append(messageParagraphs[i]) - } - - if (i != messageParagraphs.lastIndex) { - append("\n\n") - } - } - } - append("\n\n") - append(myText) - } - } - - private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) { - launchSlashCommandFlowSuspendable { - room.updateTopic(changeTopic.topic) - } - } - - private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { - launchSlashCommandFlowSuspendable { - room.invite(invite.userId, invite.reason) - } - } - - private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) { - launchSlashCommandFlowSuspendable { - room.invite3pid(invite.threePid) - } - } - - private fun handleSetUserPowerLevel(setUserPowerLevel: ParsedCommand.SetUserPowerLevel) { - val newPowerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS) - ?.content - ?.toModel() - ?.setUserPowerLevel(setUserPowerLevel.userId, setUserPowerLevel.powerLevel) - ?.toContent() - ?: return - - launchSlashCommandFlowSuspendable { - room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, newPowerLevelsContent) - } - } - - private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) { - launchSlashCommandFlowSuspendable { - session.setDisplayName(session.myUserId, changeDisplayName.displayName) - } - } - - private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { - launchSlashCommandFlowSuspendable { - room.kick(kick.userId, kick.reason) - } - } - - private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) { - launchSlashCommandFlowSuspendable { - room.ban(ban.userId, ban.reason) - } - } - - private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) { - launchSlashCommandFlowSuspendable { - room.unban(unban.userId, unban.reason) - } - } - - private fun launchSlashCommandFlow(lambda: (MatrixCallback) -> Unit) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - val matrixCallback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultOk) - } - - override fun onFailure(failure: Throwable) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandResultError(failure)) - } - } - lambda.invoke(matrixCallback) - } - - private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { - _viewEvents.post(RoomDetailViewEvents.SlashCommandHandled()) - viewModelScope.launch { - val event = try { - block() - RoomDetailViewEvents.SlashCommandResultOk - } catch (failure: Exception) { - RoomDetailViewEvents.SlashCommandResultError(failure) - } - _viewEvents.post(event) - } - } + // PRIVATE METHODS ***************************************************************************** private fun handleSendReaction(action: RoomDetailAction.SendReaction) { room.sendReaction(action.targetEventId, action.reaction) @@ -1246,32 +747,10 @@ class RoomDetailViewModel @AssistedInject constructor( } } - private fun handleEditAction(action: RoomDetailAction.EnterEditMode) { - room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> - setState { copy(sendMode = SendMode.EDIT(timelineEvent, timelineEvent.getTextEditableContent() ?: "")) } - } - } - - private fun handleQuoteAction(action: RoomDetailAction.EnterQuoteMode) { - room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> - setState { copy(sendMode = SendMode.QUOTE(timelineEvent, action.text)) } - } - } - - private fun handleReplyAction(action: RoomDetailAction.EnterReplyMode) { - room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> - setState { copy(sendMode = SendMode.REPLY(timelineEvent, action.text)) } - } - } - - private fun handleEnterRegularMode(action: RoomDetailAction.EnterRegularMode) = setState { - copy(sendMode = SendMode.REGULAR(action.text, action.fromSharing)) - } - private fun handleOpenOrDownloadFile(action: RoomDetailAction.DownloadOrOpen) { val mxcUrl = action.messageFileContent.getFileUrl() ?: return - val isLocalSendingFile = action.senderId == session.myUserId - && mxcUrl.startsWith("content://") + val isLocalSendingFile = action.senderId == session.myUserId && + mxcUrl.startsWith("content://") if (isLocalSendingFile) { tryOrNull { Uri.parse(mxcUrl) }?.let { _viewEvents.post(RoomDetailViewEvents.OpenFile( @@ -1604,7 +1083,7 @@ class RoomDetailViewModel @AssistedInject constructor( setState { val typingMessage = typingHelper.getTypingMessage(summary.typingUsers) copy( - typingMessage = typingMessage, + formattedTypingUsers = typingMessage, hasFailedSending = summary.hasFailedSending ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt index 8f4ad97b72..4c6e4ac3fe 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt @@ -25,32 +25,10 @@ import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.session.widgets.model.WidgetType -/** - * Describes the current send mode: - * REGULAR: sends the text as a regular message - * QUOTE: User is currently quoting a message - * EDIT: User is currently editing an existing message - * - * Depending on the state the bottom toolbar will change (icons/preview/actions...) - */ -sealed class SendMode(open val text: String) { - data class REGULAR( - override val text: String, - val fromSharing: Boolean, - // This is necessary for forcing refresh on selectSubscribe - private val ts: Long = System.currentTimeMillis() - ) : SendMode(text) - - data class QUOTE(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) - data class EDIT(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) - data class REPLY(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) -} - sealed class UnreadState { object Unknown : UnreadState() object HasNoUnread : UnreadState() @@ -73,8 +51,7 @@ data class RoomDetailViewState( val asyncInviter: Async = Uninitialized, val asyncRoomSummary: Async = Uninitialized, val activeRoomWidgets: Async> = Uninitialized, - val typingMessage: String? = null, - val sendMode: SendMode = SendMode.REGULAR("", false), + val formattedTypingUsers: String? = null, val tombstoneEvent: Event? = null, val joinUpgradedRoomAsync: Async = Uninitialized, val syncState: SyncState = SyncState.Idle, @@ -84,7 +61,6 @@ data class RoomDetailViewState( val unreadState: UnreadState = UnreadState.Unknown, val canShowJumpToReadMarker: Boolean = true, val changeMembershipState: ChangeMembershipState = ChangeMembershipState.Unknown, - val canSendMessage: Boolean = true, val canInvite: Boolean = true, val isAllowedToManageWidgets: Boolean = false, val isAllowedToStartWebRTCCall: Boolean = true, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index 79ff7be441..232323789c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -32,16 +32,15 @@ import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.features.html.PillImageSpan import timber.log.Timber -class ComposerEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle) - : EmojiEditText(context, attrs, defStyleAttr) { +class ComposerEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle) : + EmojiEditText(context, attrs, defStyleAttr) { interface Callback { fun onRichContentSelected(contentUri: Uri): Boolean - fun onTextBlankStateChanged(isBlank: Boolean) + fun onTextChanged(text: CharSequence) } var callback: Callback? = null - private var isBlankText = true override fun onCreateInputConnection(editorInfo: EditorInfo): InputConnection? { val ic = super.onCreateInputConnection(editorInfo) ?: return null @@ -95,11 +94,7 @@ class ComposerEditText @JvmOverloads constructor(context: Context, attrs: Attrib } spanToRemove = null } - // Report blank status of EditText to be able to arrange other elements of the composer - if (s.isBlank() != isBlankText) { - isBlankText = !isBlankText - callback?.onTextBlankStateChanged(isBlankText) - } + callback?.onTextChanged(s.toString()) } } ) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerAction.kt new file mode 100644 index 0000000000..7725400187 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerAction.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 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.detail.composer + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class TextComposerAction : VectorViewModelAction { + data class SaveDraft(val draft: String) : TextComposerAction() + data class SendMessage(val text: CharSequence, val autoMarkdown: Boolean) : TextComposerAction() + data class EnterEditMode(val eventId: String, val text: String) : TextComposerAction() + data class EnterQuoteMode(val eventId: String, val text: String) : TextComposerAction() + data class EnterReplyMode(val eventId: String, val text: String) : TextComposerAction() + data class EnterRegularMode(val text: String, val fromSharing: Boolean) : TextComposerAction() + data class UserIsTyping(val isTyping: Boolean) : TextComposerAction() + data class OnTextChanged(val text: CharSequence) : TextComposerAction() + data class OnVoiceRecordingStateChanged(val isRecording: Boolean) : TextComposerAction() +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt index eb935f9e75..34b3c1777c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt @@ -24,17 +24,14 @@ import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.core.text.toSpannable -import androidx.core.view.isInvisible -import androidx.core.view.isVisible -import androidx.transition.AutoTransition import androidx.transition.ChangeBounds import androidx.transition.Fade import androidx.transition.Transition import androidx.transition.TransitionManager import androidx.transition.TransitionSet import im.vector.app.R +import im.vector.app.core.extensions.setTextIfDifferent import im.vector.app.databinding.ComposerLayoutBinding -import org.matrix.android.sdk.api.extensions.orFalse /** * Encapsulate the timeline composer UX. @@ -61,13 +58,6 @@ class TextComposerView @JvmOverloads constructor( val text: Editable? get() = views.composerEditText.text - var alwaysShowSendButton = false - set(value) { - field = value - val shouldShowSendButton = currentConstraintSetId == R.layout.composer_layout_constraint_set_expanded || text?.isNotBlank().orFalse() || value - views.sendButton.isInvisible = !shouldShowSendButton - } - init { inflate(context, R.layout.composer_layout, this) views = ComposerLayoutBinding.bind(this) @@ -79,17 +69,8 @@ class TextComposerView @JvmOverloads constructor( return callback?.onRichContentSelected(contentUri) ?: false } - override fun onTextBlankStateChanged(isBlank: Boolean) { - val shouldShowSendButton = currentConstraintSetId == R.layout.composer_layout_constraint_set_expanded || !isBlank || alwaysShowSendButton - TransitionManager.endTransitions(this@TextComposerView) - if (views.sendButton.isVisible != shouldShowSendButton) { - TransitionManager.beginDelayedTransition( - this@TextComposerView, - AutoTransition().also { it.duration = 150 } - ) - views.sendButton.isInvisible = !shouldShowSendButton - } - callback?.onTextBlankStateChanged(isBlank) + override fun onTextChanged(text: CharSequence) { + callback?.onTextChanged(text) } } views.composerRelatedMessageCloseButton.setOnClickListener { @@ -114,9 +95,6 @@ class TextComposerView @JvmOverloads constructor( } currentConstraintSetId = R.layout.composer_layout_constraint_set_compact applyNewConstraintSet(animate, transitionComplete) - - val shouldShowSendButton = !views.composerEditText.text.isNullOrEmpty() || alwaysShowSendButton - views.sendButton.isInvisible = !shouldShowSendButton } fun expand(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) { @@ -126,10 +104,14 @@ class TextComposerView @JvmOverloads constructor( } currentConstraintSetId = R.layout.composer_layout_constraint_set_expanded applyNewConstraintSet(animate, transitionComplete) - views.sendButton.isInvisible = false + } + + fun setTextIfDifferent(text: CharSequence?): Boolean { + return views.composerEditText.setTextIfDifferent(text) } private fun applyNewConstraintSet(animate: Boolean, transitionComplete: (() -> Unit)?) { + // val wasSendButtonInvisible = views.sendButton.isInvisible if (animate) { configureAndBeginTransition(transitionComplete) } @@ -137,6 +119,8 @@ class TextComposerView @JvmOverloads constructor( it.clone(context, currentConstraintSetId) it.applyTo(this) } + // Might be updated by view state just after, but avoid blinks + // views.sendButton.isInvisible = wasSendButtonInvisible } private fun configureAndBeginTransition(transitionComplete: (() -> Unit)? = null) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt new file mode 100644 index 0000000000..691ed4d93e --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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.detail.composer + +import androidx.annotation.StringRes +import im.vector.app.core.platform.VectorViewEvents +import im.vector.app.features.command.Command + +sealed class TextComposerViewEvents : VectorViewEvents { + + data class AnimateSendButtonVisibility(val isVisible: Boolean) : TextComposerViewEvents() + + data class ShowMessage(val message: String) : TextComposerViewEvents() + + abstract class SendMessageResult : TextComposerViewEvents() + + object MessageSent : SendMessageResult() + data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult() + class SlashCommandError(val command: Command) : SendMessageResult() + class SlashCommandUnknown(val command: String) : SendMessageResult() + data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() + object SlashCommandResultOk : SendMessageResult() + class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() + + data class OpenRoomMemberProfile(val userId: String) : TextComposerViewEvents() + + // TODO Remove + object SlashCommandNotImplemented : SendMessageResult() + + data class ShowRoomUpgradeDialog(val newVersion: String, val isPublic: Boolean) : TextComposerViewEvents() +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt new file mode 100644 index 0000000000..35871611c0 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt @@ -0,0 +1,722 @@ +/* + * Copyright (c) 2021 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.detail.composer + +import androidx.lifecycle.viewModelScope +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.R +import im.vector.app.core.extensions.exhaustive +import im.vector.app.core.platform.VectorViewModel +import im.vector.app.core.resources.StringProvider +import im.vector.app.features.command.CommandParser +import im.vector.app.features.command.ParsedCommand +import im.vector.app.features.home.room.detail.ChatEffect +import im.vector.app.features.home.room.detail.RoomDetailFragment +import im.vector.app.features.home.room.detail.composer.rainbow.RainbowGenerator +import im.vector.app.features.home.room.detail.toMessageType +import im.vector.app.features.powerlevel.PowerLevelsObservableFactory +import im.vector.app.features.session.coroutineScope +import im.vector.app.features.settings.VectorPreferences +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.commonmark.parser.Parser +import org.commonmark.renderer.html.HtmlRenderer +import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent +import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent +import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.session.room.model.message.MessageType +import org.matrix.android.sdk.api.session.room.model.message.OptionItem +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper +import org.matrix.android.sdk.api.session.room.send.UserDraft +import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent +import org.matrix.android.sdk.api.session.room.timeline.getRelationContent +import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent +import org.matrix.android.sdk.api.session.space.CreateSpaceParams +import timber.log.Timber + +class TextComposerViewModel @AssistedInject constructor( + @Assisted initialState: TextComposerViewState, + private val session: Session, + private val stringProvider: StringProvider, + private val vectorPreferences: VectorPreferences, + private val rainbowGenerator: RainbowGenerator +) : VectorViewModel(initialState) { + + private val room = session.getRoom(initialState.roomId)!! + + // Keep it out of state to avoid invalidate being called + private var currentComposerText: CharSequence = "" + + init { + loadDraftIfAny() + observePowerLevel() + subscribeToStateInternal() + } + + override fun handle(action: TextComposerAction) { + Timber.v("Handle action: $action") + when (action) { + is TextComposerAction.EnterEditMode -> handleEnterEditMode(action) + is TextComposerAction.EnterQuoteMode -> handleEnterQuoteMode(action) + is TextComposerAction.EnterRegularMode -> handleEnterRegularMode(action) + is TextComposerAction.EnterReplyMode -> handleEnterReplyMode(action) + is TextComposerAction.SaveDraft -> handleSaveDraft(action) + is TextComposerAction.SendMessage -> handleSendMessage(action) + is TextComposerAction.UserIsTyping -> handleUserIsTyping(action) + is TextComposerAction.OnTextChanged -> handleOnTextChanged(action) + is TextComposerAction.OnVoiceRecordingStateChanged -> handleOnVoiceRecordingStateChanged(action) + } + } + + private fun handleOnVoiceRecordingStateChanged(action: TextComposerAction.OnVoiceRecordingStateChanged) = setState { + copy(isVoiceRecording = action.isRecording) + } + + private fun handleOnTextChanged(action: TextComposerAction.OnTextChanged) { + setState { + // Makes sure currentComposerText is upToDate when accessing further setState + currentComposerText = action.text + this + } + updateIsSendButtonVisibility(true) + } + + private fun subscribeToStateInternal() { + selectSubscribe(TextComposerViewState::sendMode, TextComposerViewState::canSendMessage, TextComposerViewState::isVoiceRecording) { _, _, _ -> + updateIsSendButtonVisibility(false) + } + } + + private fun updateIsSendButtonVisibility(triggerAnimation: Boolean) = setState { + val isSendButtonVisible = isComposerVisible && (sendMode !is SendMode.REGULAR || currentComposerText.isNotBlank()) + if (this.isSendButtonVisible != isSendButtonVisible && triggerAnimation) { + _viewEvents.post(TextComposerViewEvents.AnimateSendButtonVisibility(isSendButtonVisible)) + } + copy(isSendButtonVisible = isSendButtonVisible) + } + + private fun handleEnterRegularMode(action: TextComposerAction.EnterRegularMode) = setState { + copy(sendMode = SendMode.REGULAR(action.text, action.fromSharing)) + } + + private fun handleEnterEditMode(action: TextComposerAction.EnterEditMode) { + room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.EDIT(timelineEvent, timelineEvent.getTextEditableContent() ?: "")) } + } + } + + private fun observePowerLevel() { + PowerLevelsObservableFactory(room).createObservable() + .subscribe { + val canSendMessage = PowerLevelsHelper(it).isUserAllowedToSend(session.myUserId, false, EventType.MESSAGE) + setState { + copy(canSendMessage = canSendMessage) + } + } + .disposeOnClear() + } + + private fun handleEnterQuoteMode(action: TextComposerAction.EnterQuoteMode) { + room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.QUOTE(timelineEvent, action.text)) } + } + } + + private fun handleEnterReplyMode(action: TextComposerAction.EnterReplyMode) { + room.getTimeLineEvent(action.eventId)?.let { timelineEvent -> + setState { copy(sendMode = SendMode.REPLY(timelineEvent, action.text)) } + } + } + + private fun handleSendMessage(action: TextComposerAction.SendMessage) { + withState { state -> + when (state.sendMode) { + is SendMode.REGULAR -> { + when (val slashCommandResult = CommandParser.parseSplashCommand(action.text)) { + is ParsedCommand.ErrorNotACommand -> { + // Send the text message to the room + room.sendTextMessage(action.text, autoMarkdown = action.autoMarkdown) + _viewEvents.post(TextComposerViewEvents.MessageSent) + popDraft() + } + is ParsedCommand.ErrorSyntax -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandError(slashCommandResult.command)) + } + is ParsedCommand.ErrorEmptySlashCommand -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandUnknown("/")) + } + is ParsedCommand.ErrorUnknownSlashCommand -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandUnknown(slashCommandResult.slashCommand)) + } + is ParsedCommand.SendPlainText -> { + // Send the text message to the room, without markdown + room.sendTextMessage(slashCommandResult.message, autoMarkdown = false) + _viewEvents.post(TextComposerViewEvents.MessageSent) + popDraft() + } + is ParsedCommand.ChangeRoomName -> { + handleChangeRoomNameSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.Invite -> { + handleInviteSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.Invite3Pid -> { + handleInvite3pidSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.SetUserPowerLevel -> { + handleSetUserPowerLevel(slashCommandResult) + popDraft() + } + is ParsedCommand.ClearScalarToken -> { + // TODO + _viewEvents.post(TextComposerViewEvents.SlashCommandNotImplemented) + } + is ParsedCommand.SetMarkdown -> { + vectorPreferences.setMarkdownEnabled(slashCommandResult.enable) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled( + if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + popDraft() + } + is ParsedCommand.BanUser -> { + handleBanSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.UnbanUser -> { + handleUnbanSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.IgnoreUser -> { + handleIgnoreSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.UnignoreUser -> { + handleUnignoreSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.KickUser -> { + handleKickSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.JoinRoom -> { + handleJoinToAnotherRoomSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.PartRoom -> { + // TODO + _viewEvents.post(TextComposerViewEvents.SlashCommandNotImplemented) + } + is ParsedCommand.SendEmote -> { + room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendRainbow -> { + slashCommandResult.message.toString().let { + room.sendFormattedTextMessage(it, rainbowGenerator.generate(it)) + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendRainbowEmote -> { + slashCommandResult.message.toString().let { + room.sendFormattedTextMessage(it, rainbowGenerator.generate(it), MessageType.MSGTYPE_EMOTE) + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendSpoiler -> { + room.sendFormattedTextMessage( + "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})", + "${slashCommandResult.message}" + ) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendShrug -> { + sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendLenny -> { + sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendChatEffect -> { + sendChatEffect(slashCommandResult) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.SendPoll -> { + room.sendPoll(slashCommandResult.question, slashCommandResult.options.mapIndexed { index, s -> OptionItem(s, "$index. $s") }) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.ChangeTopic -> { + handleChangeTopicSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeDisplayName -> { + handleChangeDisplayNameSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeDisplayNameForRoom -> { + handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeRoomAvatar -> { + handleChangeRoomAvatarSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ChangeAvatarForRoom -> { + handleChangeAvatarForRoomSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.ShowUser -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + handleWhoisSlashCommand(slashCommandResult) + popDraft() + } + is ParsedCommand.DiscardSession -> { + if (room.isEncrypted()) { + session.cryptoService().discardOutboundSession(room.roomId) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } else { + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post( + TextComposerViewEvents + .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled)) + ) + } + } + is ParsedCommand.CreateSpace -> { + viewModelScope.launch(Dispatchers.IO) { + try { + val params = CreateSpaceParams().apply { + name = slashCommandResult.name + invitedUserIds.addAll(slashCommandResult.invitees) + } + val spaceId = session.spaceService().createSpace(params) + session.spaceService().getSpace(spaceId) + ?.addChildren( + state.roomId, + null, + null, + true + ) + } catch (failure: Throwable) { + _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) + } + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.AddToSpace -> { + viewModelScope.launch(Dispatchers.IO) { + try { + session.spaceService().getSpace(slashCommandResult.spaceId) + ?.addChildren( + room.roomId, + null, + null, + false + ) + } catch (failure: Throwable) { + _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) + } + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.JoinSpace -> { + viewModelScope.launch(Dispatchers.IO) { + try { + session.spaceService().joinSpace(slashCommandResult.spaceIdOrAlias) + } catch (failure: Throwable) { + _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) + } + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.LeaveRoom -> { + viewModelScope.launch(Dispatchers.IO) { + try { + session.getRoom(slashCommandResult.roomId)?.leave(null) + } catch (failure: Throwable) { + _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) + } + } + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + is ParsedCommand.UpgradeRoom -> { + _viewEvents.post( + TextComposerViewEvents.ShowRoomUpgradeDialog( + slashCommandResult.newVersion, + room.roomSummary()?.isPublic ?: false + ) + ) + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + popDraft() + } + }.exhaustive + } + is SendMode.EDIT -> { + // is original event a reply? + val inReplyTo = state.sendMode.timelineEvent.getRelationContent()?.inReplyTo?.eventId + if (inReplyTo != null) { + // TODO check if same content? + room.getTimeLineEvent(inReplyTo)?.let { + room.editReply(state.sendMode.timelineEvent, it, action.text.toString()) + } + } else { + val messageContent = state.sendMode.timelineEvent.getLastMessageContent() + val existingBody = messageContent?.body ?: "" + if (existingBody != action.text) { + room.editTextMessage(state.sendMode.timelineEvent, + messageContent?.msgType ?: MessageType.MSGTYPE_TEXT, + action.text, + action.autoMarkdown) + } else { + Timber.w("Same message content, do not send edition") + } + } + _viewEvents.post(TextComposerViewEvents.MessageSent) + popDraft() + } + is SendMode.QUOTE -> { + val messageContent = state.sendMode.timelineEvent.getLastMessageContent() + val textMsg = messageContent?.body + + val finalText = legacyRiotQuoteText(textMsg, action.text.toString()) + + // TODO check for pills? + + // TODO Refactor this, just temporary for quotes + val parser = Parser.builder().build() + val document = parser.parse(finalText) + val renderer = HtmlRenderer.builder().build() + val htmlText = renderer.render(document) + if (finalText == htmlText) { + room.sendTextMessage(finalText) + } else { + room.sendFormattedTextMessage(finalText, htmlText) + } + _viewEvents.post(TextComposerViewEvents.MessageSent) + popDraft() + } + is SendMode.REPLY -> { + state.sendMode.timelineEvent.let { + room.replyToMessage(it, action.text.toString(), action.autoMarkdown) + _viewEvents.post(TextComposerViewEvents.MessageSent) + popDraft() + } + } + }.exhaustive + } + } + + private fun popDraft() = withState { + if (it.sendMode is SendMode.REGULAR && it.sendMode.fromSharing) { + // If we were sharing, we want to get back our last value from draft + loadDraftIfAny() + } else { + // Otherwise we clear the composer and remove the draft from db + setState { copy(sendMode = SendMode.REGULAR("", false)) } + viewModelScope.launch { + room.deleteDraft() + } + } + } + + private fun loadDraftIfAny() { + val currentDraft = room.getDraft() + setState { + copy( + // Create a sendMode from a draft and retrieve the TimelineEvent + sendMode = when (currentDraft) { + is UserDraft.REGULAR -> SendMode.REGULAR(currentDraft.text, false) + is UserDraft.QUOTE -> { + room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> + SendMode.QUOTE(timelineEvent, currentDraft.text) + } + } + is UserDraft.REPLY -> { + room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> + SendMode.REPLY(timelineEvent, currentDraft.text) + } + } + is UserDraft.EDIT -> { + room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent -> + SendMode.EDIT(timelineEvent, currentDraft.text) + } + } + else -> null + } ?: SendMode.REGULAR("", fromSharing = false) + ) + } + } + + private fun handleUserIsTyping(action: TextComposerAction.UserIsTyping) { + if (vectorPreferences.sendTypingNotifs()) { + if (action.isTyping) { + room.userIsTyping() + } else { + room.userStopsTyping() + } + } + } + + private fun sendChatEffect(sendChatEffect: ParsedCommand.SendChatEffect) { + // If message is blank, convert to an emote, with default message + if (sendChatEffect.message.isBlank()) { + val defaultMessage = stringProvider.getString(when (sendChatEffect.chatEffect) { + ChatEffect.CONFETTI -> R.string.default_message_emote_confetti + ChatEffect.SNOWFALL -> R.string.default_message_emote_snow + }) + room.sendTextMessage(defaultMessage, MessageType.MSGTYPE_EMOTE) + } else { + room.sendTextMessage(sendChatEffect.message, sendChatEffect.chatEffect.toMessageType()) + } + } + + private fun handleJoinToAnotherRoomSlashCommand(command: ParsedCommand.JoinRoom) { + viewModelScope.launch { + try { + session.joinRoom(command.roomAlias, command.reason, emptyList()) + } catch (failure: Throwable) { + _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) + return@launch + } + session.getRoomSummary(command.roomAlias) + ?.roomId + ?.let { + _viewEvents.post(TextComposerViewEvents.JoinRoomCommandSuccess(it)) + } + } + } + + private fun legacyRiotQuoteText(quotedText: String?, myText: String): String { + val messageParagraphs = quotedText?.split("\n\n".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() + return buildString { + if (messageParagraphs != null) { + for (i in messageParagraphs.indices) { + if (messageParagraphs[i].isNotBlank()) { + append("> ") + append(messageParagraphs[i]) + } + + if (i != messageParagraphs.lastIndex) { + append("\n\n") + } + } + } + append("\n\n") + append(myText) + } + } + + private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) { + launchSlashCommandFlowSuspendable { + room.updateTopic(changeTopic.topic) + } + } + + private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { + launchSlashCommandFlowSuspendable { + room.invite(invite.userId, invite.reason) + } + } + + private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) { + launchSlashCommandFlowSuspendable { + room.invite3pid(invite.threePid) + } + } + + private fun handleSetUserPowerLevel(setUserPowerLevel: ParsedCommand.SetUserPowerLevel) { + val newPowerLevelsContent = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS) + ?.content + ?.toModel() + ?.setUserPowerLevel(setUserPowerLevel.userId, setUserPowerLevel.powerLevel) + ?.toContent() + ?: return + + launchSlashCommandFlowSuspendable { + room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, null, newPowerLevelsContent) + } + } + + private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) { + launchSlashCommandFlowSuspendable { + session.setDisplayName(session.myUserId, changeDisplayName.displayName) + } + } + + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { + launchSlashCommandFlowSuspendable { + room.kick(kick.userId, kick.reason) + } + } + + private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) { + launchSlashCommandFlowSuspendable { + room.ban(ban.userId, ban.reason) + } + } + + private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) { + launchSlashCommandFlowSuspendable { + room.unban(unban.userId, unban.reason) + } + } + + private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) { + launchSlashCommandFlowSuspendable { + room.updateName(changeRoomName.name) + } + } + + private fun getMyRoomMemberContent(): RoomMemberContent? { + return room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(session.myUserId)) + ?.content + ?.toModel() + } + + private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { + launchSlashCommandFlowSuspendable { + getMyRoomMemberContent() + ?.copy(displayName = changeDisplayName.displayName) + ?.toContent() + ?.let { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it) + } + } + } + + private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) { + launchSlashCommandFlowSuspendable { + room.sendStateEvent(EventType.STATE_ROOM_AVATAR, null, RoomAvatarContent(changeAvatar.url).toContent()) + } + } + + private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { + launchSlashCommandFlowSuspendable { + getMyRoomMemberContent() + ?.copy(avatarUrl = changeAvatar.url) + ?.toContent() + ?.let { + room.sendStateEvent(EventType.STATE_ROOM_MEMBER, session.myUserId, it) + } + } + } + + private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) { + launchSlashCommandFlowSuspendable { + session.ignoreUserIds(listOf(ignore.userId)) + } + } + + private fun handleUnignoreSlashCommand(unignore: ParsedCommand.UnignoreUser) { + launchSlashCommandFlowSuspendable { + session.unIgnoreUserIds(listOf(unignore.userId)) + } + } + + private fun handleWhoisSlashCommand(whois: ParsedCommand.ShowUser) { + _viewEvents.post(TextComposerViewEvents.OpenRoomMemberProfile(whois.userId)) + } + + private fun sendPrefixedMessage(prefix: String, message: CharSequence) { + val sequence = buildString { + append(prefix) + if (message.isNotEmpty()) { + append(" ") + append(message) + } + } + room.sendTextMessage(sequence) + } + + /** + * Convert a send mode to a draft and save the draft + */ + private fun handleSaveDraft(action: TextComposerAction.SaveDraft) = withState { + session.coroutineScope.launch { + when { + it.sendMode is SendMode.REGULAR && !it.sendMode.fromSharing -> { + setState { copy(sendMode = it.sendMode.copy(action.draft)) } + room.saveDraft(UserDraft.REGULAR(action.draft)) + } + it.sendMode is SendMode.REPLY -> { + setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } + room.saveDraft(UserDraft.REPLY(it.sendMode.timelineEvent.root.eventId!!, action.draft)) + } + it.sendMode is SendMode.QUOTE -> { + setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } + room.saveDraft(UserDraft.QUOTE(it.sendMode.timelineEvent.root.eventId!!, action.draft)) + } + it.sendMode is SendMode.EDIT -> { + setState { copy(sendMode = it.sendMode.copy(text = action.draft)) } + room.saveDraft(UserDraft.EDIT(it.sendMode.timelineEvent.root.eventId!!, action.draft)) + } + } + } + } + + private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { + _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + viewModelScope.launch { + val event = try { + block() + TextComposerViewEvents.SlashCommandResultOk + } catch (failure: Exception) { + TextComposerViewEvents.SlashCommandResultError(failure) + } + _viewEvents.post(event) + } + } + + @AssistedFactory + interface Factory { + fun create(initialState: TextComposerViewState): TextComposerViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel { + val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() + return fragment.textComposerViewModelFactory.create(state) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt new file mode 100644 index 0000000000..fd1dd2d0ad --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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.detail.composer + +import com.airbnb.mvrx.MvRxState +import im.vector.app.features.home.room.detail.RoomDetailArgs +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent + +/** + * Describes the current send mode: + * REGULAR: sends the text as a regular message + * QUOTE: User is currently quoting a message + * EDIT: User is currently editing an existing message + * + * Depending on the state the bottom toolbar will change (icons/preview/actions...) + */ +sealed class SendMode(open val text: String) { + data class REGULAR( + override val text: String, + val fromSharing: Boolean, + // This is necessary for forcing refresh on selectSubscribe + private val ts: Long = System.currentTimeMillis() + ) : SendMode(text) + + data class QUOTE(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) + data class EDIT(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) + data class REPLY(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text) +} + +data class TextComposerViewState( + val roomId: String, + val canSendMessage: Boolean = true, + val isVoiceRecording: Boolean = false, + val isSendButtonVisible: Boolean = false, + val sendMode: SendMode = SendMode.REGULAR("", false) +) : MvRxState { + + val isComposerVisible: Boolean + get() = canSendMessage && !isVoiceRecording + + constructor(args: RoomDetailArgs) : this(roomId = args.roomId) +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt index 0225ef2853..b0880623de 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt @@ -60,6 +60,7 @@ class VoiceMessageHelper @Inject constructor( try { voiceRecorder.startRecord() } catch (failure: Throwable) { + Timber.e(failure, "Unable to start recording") throw VoiceFailure.UnableToRecord(failure) } startRecordingAmplitudes() @@ -146,6 +147,7 @@ class VoiceMessageHelper @Inject constructor( } } } catch (failure: Throwable) { + Timber.e(failure, "Unable to start playback") throw VoiceFailure.UnableToPlay(failure) } startPlaybackTicker(id) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 1749c955c9..f7b8cead37 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -43,7 +43,7 @@ import kotlin.math.floor /** * Encapsulates the voice message recording view and animations. */ -class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Listener { +class VoiceMessageRecorderView : ConstraintLayout, VoiceMessagePlaybackTracker.Listener { interface Callback { // Return true if the recording is started @@ -260,8 +260,8 @@ class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Li val previousRecordingState = recordingState if (recordingState == RecordingState.STARTED) { // Determine if cancelling or locking for the first move action. - if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1)) - && distanceX > distanceY && distanceX > lastDistanceX) { + if (((currentX < firstX && rtlXMultiplier == 1) || (currentX > firstX && rtlXMultiplier == -1)) && + distanceX > distanceY && distanceX > lastDistanceX) { recordingState = RecordingState.CANCELLING } else if (currentY < firstY && distanceY > distanceX && distanceY > lastDistanceY) { recordingState = RecordingState.LOCKING @@ -504,12 +504,14 @@ class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Li views.voiceMessagePlaybackTimerIndicator.isVisible = true views.voicePlaybackControlButton.isVisible = false views.voiceMessageSendButton.isVisible = true + views.voicePlaybackWaveform.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES renderToast(context.getString(R.string.voice_message_tap_to_stop_toast)) } private fun showPlaybackViews() { views.voiceMessagePlaybackTimerIndicator.isVisible = false views.voicePlaybackControlButton.isVisible = true + views.voicePlaybackWaveform.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO callback?.onVoiceRecordingPlaybackModeOn() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt index c097b9adb5..7a91dae183 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptItem.kt @@ -26,6 +26,7 @@ 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.onClick +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsController.kt index f5348bd398..bf88218fa6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsController.kt @@ -30,8 +30,8 @@ import javax.inject.Inject */ class DisplayReadReceiptsController @Inject constructor(private val dateFormatter: VectorDateFormatter, private val session: Session, - private val avatarRender: AvatarRenderer) - : TypedEpoxyController>() { + private val avatarRender: AvatarRenderer) : + TypedEpoxyController>() { var listener: Listener? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt index 1debf32104..edef92ee2d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt @@ -102,9 +102,9 @@ class SearchResultController @Inject constructor( data.searchResult.forEach { eventAndSender -> val event = eventAndSender.event - @Suppress("UNCHECKED_CAST") // Take new content first - val text = ((event.content?.get("m.new_content") as? Content) ?: event.content)?.get("body") as? String ?: return@forEach + @Suppress("UNCHECKED_CAST") +val text = ((event.content?.get("m.new_content") as? Content) ?: event.content)?.get("body") as? String ?: return@forEach val spannable = setHighLightedText(text, data.highlights) ?: return@forEach val eventDate = Calendar.getInstance().apply { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt index 14ea94ffd5..c0f71ed6cc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultItem.kt @@ -26,6 +26,7 @@ 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.extensions.setTextOrHide +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 39b3cd5061..5a37a343e6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -249,8 +249,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec if (partialState.highlightedEventId != newPartialState.highlightedEventId) { // Clear cache to force a refresh for (i in 0 until modelCache.size) { - if (modelCache[i]?.eventId == viewState.highlightedEventId - || modelCache[i]?.eventId == partialState.highlightedEventId) { + if (modelCache[i]?.eventId == viewState.highlightedEventId || + modelCache[i]?.eventId == partialState.highlightedEventId) { modelCache[i] = null } } @@ -498,8 +498,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec if (vectorPreferences.labShowCompleteHistoryInEncryptedRoom()) { return } - if (event.root.type == EventType.STATE_ROOM_MEMBER - && event.root.stateKey == session.myUserId) { + if (event.root.type == EventType.STATE_ROOM_MEMBER && + event.root.stateKey == session.myUserId) { val content = event.root.content.toModel() if (content?.membership == Membership.INVITE) { hasReachedInvite = true diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index cb64c8b5ad..6de8864f10 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData - import javax.inject.Inject /** 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 6e6c7c1dbe..275d37e295 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 @@ -341,14 +341,14 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted add(EventSharedAction.AddReaction(eventId)) } - if (canQuote(timelineEvent, messageContent, actionPermissions)) { - add(EventSharedAction.Quote(eventId)) - } - if (canViewReactions(timelineEvent)) { add(EventSharedAction.ViewReactions(informationData)) } + if (canQuote(timelineEvent, messageContent, actionPermissions)) { + add(EventSharedAction.Quote(eventId)) + } + if (timelineEvent.hasBeenEdited()) { add(EventSharedAction.ViewEditHistory(informationData)) } @@ -365,14 +365,14 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted if (vectorPreferences.developerMode()) { if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) { val keysBackupService = session.cryptoService().keysBackupService() - if (keysBackupService.state == KeysBackupState.NotTrusted - || (keysBackupService.state == KeysBackupState.ReadyToBackUp - && keysBackupService.canRestoreKeys()) + if (keysBackupService.state == KeysBackupState.NotTrusted || + (keysBackupService.state == KeysBackupState.ReadyToBackUp && + keysBackupService.canRestoreKeys()) ) { add(EventSharedAction.UseKeyBackup) } - if (session.cryptoService().getCryptoDeviceInfo(session.myUserId).size > 1 - || timelineEvent.senderInfo.userId != session.myUserId) { + if (session.cryptoService().getCryptoDeviceInfo(session.myUserId).size > 1 || + timelineEvent.senderInfo.userId != session.myUserId) { add(EventSharedAction.ReRequestKey(timelineEvent.eventId)) } } @@ -435,9 +435,9 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } private fun canRetry(event: TimelineEvent, actionPermissions: ActionPermissions): Boolean { - return event.root.sendState.hasFailed() - && actionPermissions.canSendMessage - && (event.root.isAttachmentMessage() || event.root.isTextMessage()) + return event.root.sendState.hasFailed() && + actionPermissions.canSendMessage && + (event.root.isAttachmentMessage() || event.root.isTextMessage()) } private fun canViewReactions(event: TimelineEvent): Boolean { @@ -453,8 +453,8 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted // TODO if user is admin or moderator val messageContent = event.root.getClearContent().toModel() return event.root.senderId == myUserId && ( - messageContent?.msgType == MessageType.MSGTYPE_TEXT - || messageContent?.msgType == MessageType.MSGTYPE_EMOTE + messageContent?.msgType == MessageType.MSGTYPE_TEXT || + messageContent?.msgType == MessageType.MSGTYPE_EMOTE ) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt index 7be4be4b57..d8ce6e3e7a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt @@ -30,13 +30,12 @@ import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData - import javax.inject.Inject /** * Bottom sheet displaying list of edits for a given event ordered by timestamp */ -class ViewEditHistoryBottomSheet: +class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() { private val viewModel: ViewEditHistoryViewModel by fragmentViewModel(ViewEditHistoryViewModel::class) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewState.kt index 62f08eef7f..ca80c29cb4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewState.kt @@ -26,8 +26,8 @@ data class ViewEditHistoryViewState( val eventId: String, val roomId: String, val isOriginalAReply: Boolean = false, - val editList: Async> = Uninitialized) - : MvRxState { + val editList: Async> = Uninitialized) : + MvRxState { constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 25b5dc34d6..e378969b4a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -63,10 +63,9 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde currentPosition: Int, eventIdToHighlight: String?, callback: TimelineEventController.Callback?, - requestModelBuild: () -> Unit) - : BasedMergedItem<*>? { - return if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE - && event.isRoomConfiguration(nextEvent.root.getClearContent()?.toModel()?.creator)) { + requestModelBuild: () -> Unit): BasedMergedItem<*>? { + return if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE && + event.isRoomConfiguration(nextEvent.root.getClearContent()?.toModel()?.creator)) { // It's the first item before room.create // Collapse all room configuration events buildRoomCreationMergedSummary(currentPosition, items, partialState, event, eventIdToHighlight, requestModelBuild, callback) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 287cd014e9..98deaaf9c3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -69,6 +69,7 @@ import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.media.VideoContentRenderer import me.gujun.android.span.span import org.commonmark.node.Document +import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.toModel @@ -142,8 +143,8 @@ class MessageItemFactory @Inject constructor( val malformedText = stringProvider.getString(R.string.malformed_message) return defaultItemFactory.create(malformedText, informationData, highlight, callback) } - if (messageContent.relatesTo?.type == RelationType.REPLACE - || event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE + if (messageContent.relatesTo?.type == RelationType.REPLACE || + event.isEncrypted() && event.root.content.toModel()?.relatesTo?.type == RelationType.REPLACE ) { // This is an edit event, we should display it when debugging as a notice event return noticeItemFactory.create(params) @@ -213,7 +214,7 @@ class MessageItemFactory @Inject constructor( if (informationData.sentByMe && !informationData.sendState.isSent()) { it } else { - it.takeIf { it.startsWith("mxc://") } + it.takeIf { it.isMxcUrl() } } } ?: "" return MessageFileItem_() @@ -244,7 +245,7 @@ class MessageItemFactory @Inject constructor( if (informationData.sentByMe && !informationData.sendState.isSent()) { it } else { - it.takeIf { it.startsWith("mxc://") } + it.takeIf { it.isMxcUrl() } } } ?: "" diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt index 5a9af975ed..b5831b33b8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt @@ -46,8 +46,8 @@ class DisplayableEventFormatter @Inject constructor( return noticeEventFormatter.formatRedactedEvent(timelineEvent.root) } - if (timelineEvent.root.isEncrypted() - && timelineEvent.root.mxDecryptionResult == null) { + if (timelineEvent.root.isEncrypted() && + timelineEvent.root.mxDecryptionResult == null) { return stringProvider.getString(R.string.encrypted_message) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index c80a92d568..4ca1557208 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -363,8 +363,8 @@ class NoticeEventFormatter @Inject constructor( private fun formatRoomMemberEvent(event: Event, senderName: String?, isDm: Boolean): String? { val eventContent: RoomMemberContent? = event.getClearContent().toModel() val prevEventContent: RoomMemberContent? = event.resolvedPrevContent().toModel() - val isMembershipEvent = prevEventContent?.membership != eventContent?.membership - || eventContent?.membership == Membership.LEAVE + val isMembershipEvent = prevEventContent?.membership != eventContent?.membership || + eventContent?.membership == Membership.LEAVE return if (isMembershipEvent) { buildMembershipNotice(event, senderName, eventContent, prevEventContent, isDm) } else { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index da75a808d8..6385494fe1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -65,13 +65,13 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses ?: false val showInformation = - addDaySeparator - || event.senderInfo.avatarUrl != nextDisplayableEvent?.senderInfo?.avatarUrl - || event.senderInfo.disambiguatedDisplayName != nextDisplayableEvent?.senderInfo?.disambiguatedDisplayName - || nextDisplayableEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED) - || isNextMessageReceivedMoreThanOneHourAgo - || isTileTypeMessage(nextDisplayableEvent) - || nextDisplayableEvent.isEdition() + addDaySeparator || + event.senderInfo.avatarUrl != nextDisplayableEvent?.senderInfo?.avatarUrl || + event.senderInfo.disambiguatedDisplayName != nextDisplayableEvent?.senderInfo?.disambiguatedDisplayName || + nextDisplayableEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED) || + isNextMessageReceivedMoreThanOneHourAgo || + isTileTypeMessage(nextDisplayableEvent) || + nextDisplayableEvent.isEdition() val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE) val roomSummary = params.partialState.roomSummary @@ -143,10 +143,10 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration { return if ( - event.root.sendState == SendState.SYNCED - && roomSummary?.isEncrypted.orFalse() + event.root.sendState == SendState.SYNCED && + roomSummary?.isEncrypted.orFalse() && // is user verified - && session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) { + session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) { val ts = roomSummary?.encryptionEventTs ?: 0 val eventTs = event.root.originServerTs ?: 0 if (event.isEncrypted()) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineControllerInterceptorHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineControllerInterceptorHelper.kt index 736da63ee2..7165921b35 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineControllerInterceptorHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineControllerInterceptorHelper.kt @@ -65,8 +65,8 @@ class TimelineControllerInterceptorHelper(private val positionOfReadMarker: KMut } epoxyModel.getEventIds().forEach { eventId -> adapterPositionMapping[eventId] = index - appendReadMarker = appendReadMarker - || (epoxyModel.canAppendReadMarker() && eventId == firstUnreadEventId && atLeastOneVisibleItemsBeforeReadMarker) + appendReadMarker = appendReadMarker || + (epoxyModel.canAppendReadMarker() && eventId == firstUnreadEventId && atLeastOneVisibleItemsBeforeReadMarker) } } if (epoxyModel is DaySeparatorItem) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineVisibilityStateChangedListeners.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineVisibilityStateChangedListeners.kt index 33e81aeb9b..2337a6ea15 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineVisibilityStateChangedListeners.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineVisibilityStateChangedListeners.kt @@ -21,8 +21,8 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.features.home.room.detail.timeline.TimelineEventController import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -class ReadMarkerVisibilityStateChangedListener(private val callback: TimelineEventController.Callback?) - : VectorEpoxyModel.OnVisibilityStateChangedListener { +class ReadMarkerVisibilityStateChangedListener(private val callback: TimelineEventController.Callback?) : + VectorEpoxyModel.OnVisibilityStateChangedListener { override fun onVisibilityStateChanged(visibilityState: Int) { if (visibilityState == VisibilityState.VISIBLE) { @@ -32,8 +32,8 @@ class ReadMarkerVisibilityStateChangedListener(private val callback: TimelineEve } class TimelineEventVisibilityStateChangedListener(private val callback: TimelineEventController.Callback?, - private val event: TimelineEvent) - : VectorEpoxyModel.OnVisibilityStateChangedListener { + private val event: TimelineEvent) : + VectorEpoxyModel.OnVisibilityStateChangedListener { override fun onVisibilityStateChanged(visibilityState: Int) { if (visibilityState == VisibilityState.VISIBLE) { @@ -45,8 +45,8 @@ class TimelineEventVisibilityStateChangedListener(private val callback: Timeline } class MergedTimelineEventVisibilityStateChangedListener(private val callback: TimelineEventController.Callback?, - private val events: List) - : VectorEpoxyModel.OnVisibilityStateChangedListener { + private val events: List) : + VectorEpoxyModel.OnVisibilityStateChangedListener { override fun onVisibilityStateChanged(visibilityState: Int) { if (visibilityState == VisibilityState.VISIBLE) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt index 46392a494f..5f8ac822da 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt @@ -32,6 +32,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setLeftDrawable +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.timeline.MessageColorProvider diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt index 2305cc3754..1e8e96426f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt @@ -166,9 +166,9 @@ abstract class MergedRoomCreationItem : BasedMergedItem= 2)) - && roomItem?.avatarUrl.isNullOrBlank() + val shouldSetAvatar = attributes.canChangeAvatar && + (roomSummary?.isDirect == false || (isDirect && membersCount >= 2)) && + roomItem?.avatarUrl.isNullOrBlank() holder.roomAvatarImageView.isVisible = roomItem != null if (roomItem != null) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt index 9cc3be9ac1..ab15ace5cc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt @@ -33,7 +33,6 @@ import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt index c67821701a..0b3d381619 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt @@ -32,8 +32,8 @@ import javax.inject.Inject */ class ViewReactionsEpoxyController @Inject constructor( private val stringProvider: StringProvider, - private val emojiCompatWrapper: EmojiCompatWrapper) - : TypedEpoxyController() { + private val emojiCompatWrapper: EmojiCompatWrapper) : + TypedEpoxyController() { var listener: Listener? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 35d208e30e..e9e7b471f3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -23,8 +23,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.platform.EmptyAction @@ -41,8 +41,8 @@ import org.matrix.android.sdk.rx.unwrap data class DisplayReactionsViewState( val eventId: String, val roomId: String, - val mapReactionKeyToMemberList: Async> = Uninitialized) - : MvRxState { + val mapReactionKeyToMemberList: Async> = Uninitialized) : + MvRxState { constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt index 4c018c8a99..c97fae055d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt @@ -146,7 +146,7 @@ class PreviewUrlRetriever(session: Session, companion object { // One week in millis - private const val CACHE_VALIDITY: Long = 7 * 24 * 3_600 * 1_000 + private const val CACHE_VALIDITY = 604_800_000L // 7 * 24 * 3_600 * 1_000 private val blockedDomains = listOf( "https://matrix.to", diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt index f5d09efd18..3e08ce5589 100755 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt @@ -26,7 +26,6 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.databinding.ViewUrlPreviewBinding import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.media.ImageContentRenderer - import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.media.PreviewUrlData diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt index 3dc5d0e3ba..71dc794cb0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt @@ -34,8 +34,8 @@ import org.matrix.android.sdk.api.session.Session class MigrateRoomViewModel @AssistedInject constructor( @Assisted initialState: MigrateRoomViewState, private val session: Session, - private val upgradeRoomViewModelTask: UpgradeRoomViewModelTask) - : VectorViewModel(initialState) { + private val upgradeRoomViewModelTask: UpgradeRoomViewModelTask) : + VectorViewModel(initialState) { init { val room = session.getRoom(initialState.roomId) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt index 4492361832..b934136dc2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt @@ -22,7 +22,6 @@ import android.view.View import android.widget.RelativeLayout import im.vector.app.R import im.vector.app.databinding.ViewRoomWidgetsBannerBinding - import org.matrix.android.sdk.api.session.widgets.model.Widget class RoomWidgetsBannerView @JvmOverloads constructor( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt index 4e77873522..ab6eb2e658 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt @@ -33,7 +33,6 @@ import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailViewModel import im.vector.app.features.home.room.detail.RoomDetailViewState import im.vector.app.features.navigation.Navigator - import org.matrix.android.sdk.api.session.widgets.model.Widget import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt index 14f8b53970..2da3dab16a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt @@ -30,8 +30,8 @@ import javax.inject.Inject */ class RoomWidgetsController @Inject constructor( val stringProvider: StringProvider, - val colorProvider: ColorProvider) - : TypedEpoxyController>() { + val colorProvider: ColorProvider) : + TypedEpoxyController>() { var listener: Listener? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomFooterItem.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomFooterItem.kt index 5e45004579..4c163f2f56 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomFooterItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomFooterItem.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.filtered import android.widget.Button +import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R @@ -33,11 +34,21 @@ abstract class FilteredRoomFooterItem : VectorEpoxyModel - : EpoxyController(), CollapsableControllerExtension { +abstract class CollapsableTypedEpoxyController : + EpoxyController(), CollapsableControllerExtension { private var currentData: T? = null private var allowModelBuildRequests = false @@ -43,8 +43,8 @@ abstract class CollapsableTypedEpoxyController override fun requestModelBuild() { check(allowModelBuildRequests) { - ("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a " - + "model refresh with new data.") + ("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a " + + "model refresh with new data.") } super.requestModelBuild() } @@ -57,8 +57,8 @@ abstract class CollapsableTypedEpoxyController override fun requestDelayedModelBuild(delayMs: Int) { check(allowModelBuildRequests) { - ("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a " - + "model refresh with new data.") + ("You cannot call `requestModelBuild` directly. Call `setData` instead to trigger a " + + "model refresh with new data.") } super.requestDelayedModelBuild(delayMs) } @@ -69,8 +69,8 @@ abstract class CollapsableTypedEpoxyController override fun buildModels() { check(isBuildingModels()) { - ("You cannot call `buildModels` directly. Call `setData` instead to trigger a model " - + "refresh with new data.") + ("You cannot call `buildModels` directly. Call `setData` instead to trigger a model " + + "refresh with new data.") } if (collapsed) { buildModels(null) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomInvitationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomInvitationItem.kt index b0cc8fec6c..4413776636 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomInvitationItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomInvitationItem.kt @@ -28,6 +28,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.ButtonStateView +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.invite.InviteButtonStateBinder import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt index 22cd0ae639..00d59f4c37 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt @@ -24,6 +24,7 @@ import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem import im.vector.app.features.home.room.filtered.filteredRoomFooterItem +import im.vector.app.space import javax.inject.Inject class RoomListFooterController @Inject constructor( @@ -41,6 +42,7 @@ class RoomListFooterController @Inject constructor( id("filter_footer") listener(host.listener) currentFilter(data.roomFilter) + inSpace(data.currentRoomGrouping.invoke()?.space() != null) } } else -> { 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 fdfe171439..f9ee303e1c 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 @@ -415,8 +415,8 @@ class RoomListFragment @Inject constructor( } private fun checkEmptyState() { - val shouldShowEmpty = adapterInfosList.all { it.sectionHeaderAdapter.roomsSectionData.isHidden } - && !adapterInfosList.any { it.sectionHeaderAdapter.roomsSectionData.isLoading } + val shouldShowEmpty = adapterInfosList.all { it.sectionHeaderAdapter.roomsSectionData.isHidden } && + !adapterInfosList.any { it.sectionHeaderAdapter.roomsSectionData.isLoading } if (shouldShowEmpty) { val emptyState = when (roomListParams.displayMode) { RoomListDisplayMode.NOTIFICATIONS -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt index 019a6ceddf..2b3152f8cf 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt @@ -19,7 +19,7 @@ package im.vector.app.features.home.room.list import im.vector.app.features.home.RoomListDisplayMode interface RoomListSectionBuilder { - fun buildSections(mode: RoomListDisplayMode) : List + fun buildSections(mode: RoomListDisplayMode): List fun dispose() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 11f92284a6..b7a2d4e26b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -30,6 +30,7 @@ import im.vector.app.RoomGroupingMethod import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.features.displayname.getBestName import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.Dispatchers @@ -41,6 +42,7 @@ import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.room.state.isPublic +import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.rx.rx import timber.log.Timber import javax.inject.Inject @@ -72,11 +74,13 @@ class RoomListViewModel @Inject constructor( * If current space is null, will return orphan rooms only */ ORPHANS_IF_SPACE_NULL, + /** * Special case when we don't want to discriminate rooms when current space is null. * In this case return all. */ ALL_IF_SPACE_NULL, + /** Do not filter based on space*/ NONE } @@ -93,7 +97,7 @@ class RoomListViewModel @Inject constructor( } session.rx().liveUser(session.myUserId) - .map { it.getOrNull()?.getBestName() } + .map { it.getOrNull()?.toMatrixItem()?.getBestName() } .distinctUntilChanged() .execute { copy( diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt index 6b269356c7..e017a8fe08 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt @@ -28,8 +28,8 @@ class RoomListViewModelFactory @Inject constructor(private val session: Provider private val appStateHandler: AppStateHandler, private val stringProvider: StringProvider, private val vectorPreferences: VectorPreferences, - private val autoAcceptInvites: AutoAcceptInvites) - : RoomListViewModel.Factory { + private val autoAcceptInvites: AutoAcceptInvites) : + RoomListViewModel.Factory { override fun create(initialState: RoomListViewState): RoomListViewModel { return RoomListViewModel( 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 6cfd04738a..e4abbeb1ff 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 @@ -33,6 +33,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide 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.themes.ThemeUtils import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt index 6f93599d02..2d61da0dd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsSharedAction.kt @@ -24,8 +24,8 @@ import im.vector.app.core.platform.VectorSharedAction sealed class RoomListQuickActionsSharedAction( @StringRes val titleRes: Int, @DrawableRes val iconResId: Int?, - val destructive: Boolean = false) - : VectorSharedAction { + val destructive: Boolean = false) : + VectorSharedAction { data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActionsSharedAction( R.string.room_list_quick_actions_notifications_all_noisy, diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt index 083b843b33..312e2766cc 100644 --- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt @@ -21,8 +21,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents diff --git a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt index 76947e8d3d..c1040a8cc0 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt @@ -30,6 +30,7 @@ import com.bumptech.glide.request.transition.Transition import com.google.android.material.chip.ChipDrawable import im.vector.app.R import im.vector.app.core.glide.GlideRequests +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.session.room.send.MatrixItemSpan import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index 716baff757..f8a2ee5137 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -20,8 +20,8 @@ import android.content.Context import android.text.Spannable import android.text.Spanned import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.glide.GlideApp import im.vector.app.features.home.AvatarRenderer @@ -35,8 +35,8 @@ import org.matrix.android.sdk.api.util.toMatrixItem class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomId: String?, private val context: Context, private val avatarRenderer: AvatarRenderer, - private val sessionHolder: ActiveSessionHolder) - : EventHtmlRenderer.PostProcessor { + private val sessionHolder: ActiveSessionHolder) : + EventHtmlRenderer.PostProcessor { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt index 2f20fef3c9..49ff8bde0d 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt @@ -21,8 +21,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -34,8 +34,8 @@ import org.matrix.android.sdk.rx.rx class InviteUsersToRoomViewModel @AssistedInject constructor(@Assisted initialState: InviteUsersToRoomViewState, session: Session, - val stringProvider: StringProvider) - : VectorViewModel(initialState) { + val stringProvider: StringProvider) : + VectorViewModel(initialState) { private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt index b2919d59b8..22f9e9a18c 100644 --- a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt +++ b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt @@ -30,8 +30,8 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class VectorInviteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : ConstraintLayout(context, attrs, defStyle) { +class VectorInviteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + ConstraintLayout(context, attrs, defStyle) { interface Callback { fun onAcceptInvite() diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index a0b8efd5aa..39105185b1 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -27,13 +27,12 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import im.vector.app.databinding.ActivityProgressBinding +import im.vector.app.features.home.HomeActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.permalink.PermalinkHandler -import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.permalinks.PermalinkService import timber.log.Timber -import java.util.concurrent.TimeUnit import javax.inject.Inject /** @@ -45,30 +44,38 @@ class LinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var errorFormatter: ErrorFormatter @Inject lateinit var permalinkHandler: PermalinkHandler + override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) + override fun injectWith(injector: ScreenComponent) { injector.inject(this) } - override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) - override fun initUiAndData() { + handleIntent() + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + handleIntent() + } + + private fun handleIntent() { val uri = intent.data - - if (uri == null) { - // Should not happen - Timber.w("Uri is null") - finish() - return - } - - if (uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null) { - handleConfigUrl(uri) - } else if (SUPPORTED_HOSTS.contains(uri.host)) { - handleSupportedHostUrl(uri) - } else { - // Other links are not yet handled, but should not come here (manifest configuration error?) - toast(R.string.universal_link_malformed) - finish() + when { + uri == null -> { + // Should not happen + Timber.w("Uri is null") + finish() + } + uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null -> handleConfigUrl(uri) + uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> handleSupportedHostUrl() + uri.toString().startsWith(PermalinkHandler.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> handleSupportedHostUrl() + resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host) -> handleSupportedHostUrl() + else -> { + // Other links are not yet handled, but should not come here (manifest configuration error?) + toast(R.string.universal_link_malformed) + finish() + } } } @@ -81,53 +88,28 @@ class LinkHandlerActivity : VectorBaseActivity() { } } - private fun handleSupportedHostUrl(uri: Uri) { + private fun handleSupportedHostUrl() { + // If we are not logged in, open login screen. + // In the future, we might want to relaunch the process after login. if (!sessionHolder.hasActiveSession()) { - startLoginActivity(uri) - finish() - } else { - convertUriToPermalink(uri)?.let { permalink -> - startPermalinkHandler(permalink) - } ?: run { - // Host is correct but we do not recognize path - Timber.w("Unable to handle this uri: $uri") - finish() - } + startLoginActivity() + return } + + // We forward intent to HomeActivity (singleTask) to avoid the dueling app problem + // https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances + intent.setClass(this, HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP + startActivity(intent) } /** - * Convert a URL of element web instance to a matrix.to url - * Examples: - * - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org - * - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org + * Start the login screen with identity server and homeserver pre-filled, if any */ - private fun convertUriToPermalink(uri: Uri): String? { - val uriString = uri.toString() - val path = SUPPORTED_PATHS.find { it in uriString } ?: return null - return PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path) - } - - private fun startPermalinkHandler(permalink: String) { - permalinkHandler.launch(this, permalink, buildTask = true) - .delay(500, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { isHandled -> - if (!isHandled) { - toast(R.string.universal_link_malformed) - } - finish() - } - .disposeOnDestroy() - } - - /** - * Start the login screen with identity server and homeserver pre-filled - */ - private fun startLoginActivity(uri: Uri) { + private fun startLoginActivity(uri: Uri? = null) { navigator.openLogin( context = this, - loginConfig = LoginConfig.parse(uri), + loginConfig = uri?.let { LoginConfig.parse(uri) }, flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK ) finish() @@ -173,21 +155,4 @@ class LinkHandlerActivity : VectorBaseActivity() { .setPositiveButton(R.string.ok) { _, _ -> finish() } .show() } - - companion object { - private val SUPPORTED_HOSTS = listOf( - // Regular Element Web instance - "app.element.io", - // Other known instances of Element Web - "develop.element.io", - "staging.element.io", - // Previous Web instance, kept for compatibility reason - "riot.im" - ) - private val SUPPORTED_PATHS = listOf( - "/#/room/", - "/#/user/", - "/#/group/" - ) - } } diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt index 3cb5435c17..8b83873142 100644 --- a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt @@ -37,7 +37,7 @@ import javax.net.ssl.HttpsURLConnection /** * Parent Fragment for all the login/registration screens */ -abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed { +abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed { protected val loginViewModel: LoginViewModel by activityViewModel() @@ -83,8 +83,8 @@ abstract class AbstractLoginFragment : VectorBaseFragment() /* Ignore this error, user has cancelled the action */ Unit is Failure.ServerError -> - if (throwable.error.code == MatrixError.M_FORBIDDEN - && throwable.httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */) { + if (throwable.error.code == MatrixError.M_FORBIDDEN && + throwable.httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */) { MaterialAlertDialogBuilder(requireActivity()) .setTitle(R.string.dialog_title_error) .setMessage(getString(R.string.login_registration_disabled)) diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt index 3fc5037ae7..8663b7c73f 100644 --- a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt @@ -25,7 +25,7 @@ import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.withState import im.vector.app.core.utils.openUrlInChromeCustomTab -abstract class AbstractSSOLoginFragment : AbstractLoginFragment() { +abstract class AbstractSSOLoginFragment : AbstractLoginFragment() { // For sso private var customTabsServiceConnection: CustomTabsServiceConnection? = null diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 07dfc62602..f0a1b1f937 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -21,7 +21,6 @@ import android.content.Intent import android.view.View import android.view.ViewGroup import androidx.annotation.CallSuper -import com.google.android.material.appbar.MaterialToolbar import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.isVisible @@ -30,6 +29,7 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState +import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.di.ScreenComponent @@ -45,7 +45,6 @@ import im.vector.app.features.login.terms.LoginTermsFragment import im.vector.app.features.login.terms.LoginTermsFragmentArgument import im.vector.app.features.login.terms.toLocalizedLoginTerms import im.vector.app.features.pin.UnlockedActivity - import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull diff --git a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt index 016e4ca0c7..c613cf93d5 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt @@ -37,7 +37,6 @@ import im.vector.app.core.extensions.toReducedUrl import im.vector.app.databinding.FragmentLoginBinding import io.reactivex.Observable import io.reactivex.rxkotlin.subscribeBy - import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.failure.isInvalidPassword @@ -251,8 +250,8 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment { val error = state.asyncLoginAction.error - if (error is Failure.ServerError - && error.error.code == MatrixError.M_FORBIDDEN - && error.error.message.isEmpty()) { + if (error is Failure.ServerError && + error.error.code == MatrixError.M_FORBIDDEN && + error.error.message.isEmpty()) { // Login with email, but email unknown views.loginFieldTil.error = getString(R.string.login_login_with_email_error) } else { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginMode.kt b/vector/src/main/java/im/vector/app/features/login/LoginMode.kt index 2be198ab96..00945968fb 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginMode.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginMode.kt @@ -29,7 +29,7 @@ sealed class LoginMode : Parcelable @Parcelize object Unsupported : LoginMode() } -fun LoginMode.ssoIdentityProviders() : List? { +fun LoginMode.ssoIdentityProviders(): List? { return when (this) { is LoginMode.Sso -> ssoIdentityProviders is LoginMode.SsoAndPassword -> ssoIdentityProviders @@ -37,7 +37,7 @@ fun LoginMode.ssoIdentityProviders() : List? { } } -fun LoginMode.hasSso() : Boolean { +fun LoginMode.hasSso(): Boolean { return when (this) { is LoginMode.Sso -> true is LoginMode.SsoAndPassword -> true diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt index 07c27ab296..cc113b1eed 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt @@ -27,13 +27,12 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.jakewharton.rxbinding3.widget.textChanges import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard -import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.hidePassword +import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.toReducedUrl import im.vector.app.databinding.FragmentLoginResetPasswordBinding import io.reactivex.Observable import io.reactivex.rxkotlin.subscribeBy - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt index c5551bce91..67a7247130 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt @@ -25,7 +25,6 @@ import com.airbnb.mvrx.Success import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.databinding.FragmentLoginResetPasswordMailConfirmationBinding - import org.matrix.android.sdk.api.failure.is401 import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt index 059195dbce..8300326b27 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt @@ -21,7 +21,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import im.vector.app.databinding.FragmentLoginResetPasswordSuccessBinding - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt index 0c81c47129..2d40ea818a 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt @@ -23,7 +23,6 @@ import android.view.ViewGroup import im.vector.app.R import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.databinding.FragmentLoginServerSelectionBinding - import me.gujun.android.span.span import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt index 538e4700de..d0b4d65b19 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt @@ -33,7 +33,6 @@ import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.utils.ensureProtocol import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.databinding.FragmentLoginServerUrlFormBinding - import org.matrix.android.sdk.api.failure.Failure import java.net.UnknownHostException import javax.inject.Inject @@ -144,8 +143,8 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment LoginMode.SsoAndPassword(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password - else -> LoginMode.Unsupported + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) && + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password + else -> LoginMode.Unsupported } // FIXME We should post a view event here normally? @@ -798,8 +798,8 @@ class LoginViewModel @AssistedInject constructor( loginModeSupportedTypes = data.supportedLoginTypes.toList() ) } - if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) - || data.isOutdatedHomeserver) { + if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) || + data.isOutdatedHomeserver) { // Notify the UI _viewEvents.post(LoginViewEvents.OutdatedHomeserver) } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt index 187d39d9eb..d6f2c8f087 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt @@ -51,20 +51,20 @@ data class LoginViewState( // Network result @PersistState val loginMode: LoginMode = LoginMode.Unknown, - @PersistState // Supported types for the login. We cannot use a sealed class for LoginType because it is not serializable - val loginModeSupportedTypes: List = emptyList(), + @PersistState +val loginModeSupportedTypes: List = emptyList(), val knownCustomHomeServersUrls: List = emptyList() ) : MvRxState { fun isLoading(): Boolean { - return asyncLoginAction is Loading - || asyncHomeServerLoginFlowRequest is Loading - || asyncResetPassword is Loading - || asyncResetMailConfirmed is Loading - || asyncRegistration is Loading + return asyncLoginAction is Loading || + asyncHomeServerLoginFlowRequest is Loading || + asyncResetPassword is Loading || + asyncResetMailConfirmed is Loading || + asyncRegistration is Loading || // Keep loading when it is success because of the delay to switch to the next Activity - || asyncLoginAction is Success + asyncLoginAction is Success } fun isUserLogged(): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index f01bf01029..0eee121854 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -37,7 +37,6 @@ import im.vector.app.core.utils.AssetReader import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel - import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt b/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt index 4dc688ad22..f40cad9ec5 100644 --- a/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt +++ b/vector/src/main/java/im/vector/app/features/login/SocialLoginButtonsView.kt @@ -27,8 +27,8 @@ import com.google.android.material.button.MaterialButton import im.vector.app.R import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider -class SocialLoginButtonsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : LinearLayout(context, attrs, defStyle) { +class SocialLoginButtonsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + LinearLayout(context, attrs, defStyle) { interface InteractionListener { fun onProviderSelected(id: String?) diff --git a/vector/src/main/java/im/vector/app/features/login/SupportedStage.kt b/vector/src/main/java/im/vector/app/features/login/SupportedStage.kt index d9036f9ee4..5ff00f7e85 100644 --- a/vector/src/main/java/im/vector/app/features/login/SupportedStage.kt +++ b/vector/src/main/java/im/vector/app/features/login/SupportedStage.kt @@ -22,9 +22,9 @@ import org.matrix.android.sdk.api.auth.registration.Stage * Stage.Other is not supported, as well as any other new stages added to the SDK before it is added to the list below */ fun Stage.isSupported(): Boolean { - return this is Stage.ReCaptcha - || this is Stage.Dummy - || this is Stage.Msisdn - || this is Stage.Terms - || this is Stage.Email + return this is Stage.ReCaptcha || + this is Stage.Dummy || + this is Stage.Msisdn || + this is Stage.Terms || + this is Stage.Email } diff --git a/vector/src/main/java/im/vector/app/features/login2/AbstractSSOLoginFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/AbstractSSOLoginFragment2.kt index b12d9638dc..43f301d9b4 100644 --- a/vector/src/main/java/im/vector/app/features/login2/AbstractSSOLoginFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/AbstractSSOLoginFragment2.kt @@ -27,7 +27,7 @@ import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.features.login.hasSso import im.vector.app.features.login.ssoIdentityProviders -abstract class AbstractSSOLoginFragment2 : AbstractLoginFragment2() { +abstract class AbstractSSOLoginFragment2 : AbstractLoginFragment2() { // For sso private var customTabsServiceConnection: CustomTabsServiceConnection? = null diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index 60eb1934d0..a640f02279 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -21,7 +21,6 @@ import android.content.Intent import android.view.View import android.view.ViewGroup import androidx.annotation.CallSuper -import com.google.android.material.appbar.MaterialToolbar import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.isVisible @@ -29,6 +28,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import com.airbnb.mvrx.viewModel +import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.di.ScreenComponent @@ -52,7 +52,6 @@ import im.vector.app.features.login.terms.toLocalizedLoginTerms import im.vector.app.features.login2.created.AccountCreatedFragment import im.vector.app.features.login2.terms.LoginTermsFragment2 import im.vector.app.features.pin.UnlockedActivity - import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSigninUsername2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSigninUsername2.kt index 10fe0aae3a..95862a4e90 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSigninUsername2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSigninUsername2.kt @@ -95,9 +95,9 @@ class LoginFragmentSigninUsername2 @Inject constructor() : AbstractLoginFragment } override fun onError(throwable: Throwable) { - if (throwable is Failure.ServerError - && throwable.error.code == MatrixError.M_FORBIDDEN - && throwable.error.message.isEmpty()) { + if (throwable is Failure.ServerError && + throwable.error.code == MatrixError.M_FORBIDDEN && + throwable.error.message.isEmpty()) { // Login with email, but email unknown views.loginFieldTil.error = getString(R.string.login_login_with_email_error) } else { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt index 8a12b7e9b6..a889c870a0 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt @@ -162,13 +162,13 @@ class LoginFragmentToAny2 @Inject constructor() : AbstractSSOLoginFragment2) : LoginViewEvents2() @@ -57,7 +57,7 @@ sealed class LoginViewEvents2 : VectorViewEvents { data class OnWebLoginError(val errorCode: Int, val description: String, val failingUrl: String) : LoginViewEvents2() - data class OnSessionCreated(val newAccount: Boolean): LoginViewEvents2() + data class OnSessionCreated(val newAccount: Boolean) : LoginViewEvents2() object Finish : LoginViewEvents2() } 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 e3f97a1c01..2c06352868 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 @@ -587,16 +587,16 @@ class LoginViewModel2 @AssistedInject constructor( return@launch } when (data) { - is WellknownResult.Prompt -> + is WellknownResult.Prompt -> onWellknownSuccess(action, data, homeServerConnectionConfig) - is WellknownResult.FailPrompt -> + is WellknownResult.FailPrompt -> // Relax on IS discovery if homeserver is valid if (data.homeServerUrl != null && data.wellKnown != null) { onWellknownSuccess(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), homeServerConnectionConfig) } else { onWellKnownError() } - else -> { + else -> { onWellKnownError() } }.exhaustive @@ -630,11 +630,11 @@ class LoginViewModel2 @AssistedInject constructor( } ?: return val loginMode = when { - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) - && data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password - else -> LoginMode.Unsupported + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) && + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password + else -> LoginMode.Unsupported } val viewEvent = when (loginMode) { @@ -662,8 +662,8 @@ class LoginViewModel2 @AssistedInject constructor( ) } - if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) - || data.isOutdatedHomeserver) { + if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) || + data.isOutdatedHomeserver) { // Notify the UI _viewEvents.post(LoginViewEvents2.OutdatedHomeserver) } @@ -688,8 +688,8 @@ class LoginViewModel2 @AssistedInject constructor( private fun onFlowResponse(flowResult: FlowResult) { // If dummy stage is mandatory, and password is already sent, do the dummy stage now - if (isRegistrationStarted - && flowResult.missingStages.any { it is Stage.Dummy && it.mandatory }) { + if (isRegistrationStarted && + flowResult.missingStages.any { it is Stage.Dummy && it.mandatory }) { handleRegisterDummy() } else { // Notify the user @@ -757,11 +757,11 @@ class LoginViewModel2 @AssistedInject constructor( rememberHomeServer(homeServerConnectionConfig.homeServerUri.toString()) val loginMode = when { - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) - && data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password - else -> LoginMode.Unsupported + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) && + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password + else -> LoginMode.Unsupported } val viewEvent = when (loginMode) { @@ -802,8 +802,8 @@ class LoginViewModel2 @AssistedInject constructor( } viewEvent?.let { _viewEvents.post(it) } - if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) - || data.isOutdatedHomeserver) { + if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) || + data.isOutdatedHomeserver) { // Notify the UI _viewEvents.post(LoginViewEvents2.OutdatedHomeserver) } 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 b1e3eaf098..b0741f6520 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 @@ -38,7 +38,6 @@ import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.login.JavascriptResponse import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel - import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt index bb190943a7..e3d25ef283 100644 --- a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt @@ -33,6 +33,7 @@ import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.FragmentLoginAccountCreatedBinding +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider import im.vector.app.features.login2.AbstractLoginFragment2 diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 3e75b96c32..bf3e7a5d78 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -36,7 +36,6 @@ import im.vector.app.databinding.BottomSheetMatrixToCardBinding import im.vector.app.features.home.AvatarRenderer import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.permalinks.PermalinkData -import java.lang.ref.WeakReference import javax.inject.Inject import kotlin.reflect.KClass @@ -57,13 +56,7 @@ class MatrixToBottomSheet : injector.inject(this) } - private var weakReference = WeakReference(null) - - var interactionListener: InteractionListener? - set(value) { - weakReference = WeakReference(value) - } - get() = weakReference.get() + var interactionListener: InteractionListener? = null override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetMatrixToCardBinding { return BottomSheetMatrixToCardBinding.inflate(inflater, container, false) @@ -72,8 +65,8 @@ class MatrixToBottomSheet : private val viewModel by fragmentViewModel(MatrixToBottomSheetViewModel::class) interface InteractionListener { - fun navigateToRoom(roomId: String) - fun switchToSpace(spaceId: String) {} + fun mxToBottomSheetNavigateToRoom(roomId: String) + fun mxToBottomSheetSwitchToSpace(spaceId: String) } override fun invalidate() = withState(viewModel) { state -> @@ -112,12 +105,12 @@ class MatrixToBottomSheet : viewModel.observeViewEvents { when (it) { is MatrixToViewEvents.NavigateToRoom -> { - interactionListener?.navigateToRoom(it.roomId) + interactionListener?.mxToBottomSheetNavigateToRoom(it.roomId) dismiss() } MatrixToViewEvents.Dismiss -> dismiss() is MatrixToViewEvents.NavigateToSpace -> { - interactionListener?.switchToSpace(it.spaceId) + interactionListener?.mxToBottomSheetSwitchToSpace(it.spaceId) dismiss() } is MatrixToViewEvents.ShowModalError -> { @@ -131,14 +124,13 @@ class MatrixToBottomSheet : } companion object { - fun withLink(matrixToLink: String, listener: InteractionListener?): MatrixToBottomSheet { + fun withLink(matrixToLink: String): MatrixToBottomSheet { return MatrixToBottomSheet().apply { arguments = Bundle().apply { putParcelable(MvRx.KEY_ARG, MatrixToArgs( matrixToLink = matrixToLink )) } - interactionListener = listener } } } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index 566cf769f2..f78724d454 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -50,8 +50,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( private val session: Session, private val stringProvider: StringProvider, private val directRoomHelper: DirectRoomHelper, - private val errorFormatter: ErrorFormatter) - : VectorViewModel(initialState) { + private val errorFormatter: ErrorFormatter) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 6b4ed34cfb..28d16adcbb 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -24,7 +24,6 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBigImageViewerBinding - import javax.inject.Inject /** 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 fd163f7a34..debdf3739c 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 @@ -257,17 +257,11 @@ class DefaultNavigator @Inject constructor( override fun openMatrixToBottomSheet(context: Context, link: String) { if (context is AppCompatActivity) { - val listener = object : MatrixToBottomSheet.InteractionListener { - override fun navigateToRoom(roomId: String) { - openRoom(context, roomId) - } - - override fun switchToSpace(spaceId: String) { - this@DefaultNavigator.switchToSpace(context, spaceId, Navigator.PostSwitchSpaceAction.None) - } + if (context !is MatrixToBottomSheet.InteractionListener) { + fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast()) } // TODO check if there is already one?? - MatrixToBottomSheet.withLink(link, listener) + MatrixToBottomSheet.withLink(link) .show(context.supportFragmentManager, "HA#MatrixToBottomSheet") } } @@ -359,6 +353,11 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } + override fun openSettings(context: Context, payload: SettingsActivityPayload) { + val intent = VectorSettingsActivity.getIntent(context, payload) + context.startActivity(intent) + } + override fun openDebug(context: Context) { context.startActivity(Intent(context, DebugMenuActivity::class.java)) } @@ -366,8 +365,8 @@ class DefaultNavigator @Inject constructor( override fun openKeysBackupSetup(context: Context, showManualExport: Boolean) { // if cross signing is enabled and trusted or not set up at all we should propose full 4S sessionHolder.getSafeActiveSession()?.let { session -> - if (session.cryptoService().crossSigningService().getMyCrossSigningKeys() == null - || session.cryptoService().crossSigningService().canCrossSign()) { + if (session.cryptoService().crossSigningService().getMyCrossSigningKeys() == null || + session.cryptoService().crossSigningService().canCrossSign()) { (context as? AppCompatActivity)?.let { BootstrapBottomSheet.show(it.supportFragmentManager, SetupMode.NORMAL) } 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 ffe9562761..612643c804 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 @@ -23,6 +23,7 @@ import android.view.View import androidx.activity.result.ActivityResultLauncher import androidx.core.util.Pair import im.vector.app.features.crypto.recover.SetupMode +import im.vector.app.features.displayname.getBestName import im.vector.app.features.login.LoginConfig import im.vector.app.features.media.AttachmentData import im.vector.app.features.pin.PinMode @@ -82,6 +83,8 @@ interface Navigator { fun openSettings(context: Context, directAccess: Int = VectorSettingsActivity.EXTRA_DIRECT_ACCESS_ROOT) + fun openSettings(context: Context, payload: SettingsActivityPayload) + fun openDebug(context: Context) fun openKeysBackupSetup(context: Context, showManualExport: Boolean) diff --git a/vector/src/main/java/im/vector/app/features/navigation/SettingsActivityPayload.kt b/vector/src/main/java/im/vector/app/features/navigation/SettingsActivityPayload.kt new file mode 100644 index 0000000000..0b128c51b1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/navigation/SettingsActivityPayload.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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.navigation + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +sealed interface SettingsActivityPayload : Parcelable { + + @Parcelize object Root : SettingsActivityPayload + @Parcelize object AdvancedSettings : SettingsActivityPayload + @Parcelize object SecurityPrivacy : SettingsActivityPayload + @Parcelize object SecurityPrivacyManageSessions : SettingsActivityPayload + @Parcelize object General : SettingsActivityPayload + @Parcelize object Notifications : SettingsActivityPayload + + @Parcelize + data class DiscoverySettings(val expandIdentityPolicies: Boolean = false) : SettingsActivityPayload +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index a19d579c05..63c296f418 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -19,6 +19,7 @@ import androidx.core.app.NotificationCompat import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.resources.StringProvider +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter import im.vector.app.features.home.room.detail.timeline.format.NoticeEventFormatter import org.matrix.android.sdk.api.extensions.orFalse @@ -34,6 +35,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getEditedEventId +import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import timber.log.Timber import java.util.UUID @@ -107,7 +109,7 @@ class NotifiableEventResolver @Inject constructor( displayIndex = 0, senderInfo = SenderInfo( userId = user.userId, - displayName = user.getBestName(), + displayName = user.toMatrixItem().getBestName(), isUniqueDisplayName = true, avatarUrl = user.avatarUrl ) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index fea4716b39..37de7b1a75 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -27,11 +27,13 @@ import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.FirstThrottler +import im.vector.app.features.displayname.getBestName import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences import me.gujun.android.span.span import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentUrlResolver +import org.matrix.android.sdk.api.util.toMatrixItem import timber.log.Timber import java.io.File import java.io.FileOutputStream @@ -119,9 +121,9 @@ class NotificationDrawerManager @Inject constructor(private val context: Context // This is an edition val eventBeforeEdition = eventList.firstOrNull { // Edition of an event - it.eventId == notifiableEvent.editedEventId + it.eventId == notifiableEvent.editedEventId || // or edition of an edition - || it.editedEventId == notifiableEvent.editedEventId + it.editedEventId == notifiableEvent.editedEventId } if (eventBeforeEdition != null) { @@ -228,7 +230,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val user = session.getUser(session.myUserId) // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash - val myUserDisplayName = user?.getBestName() ?: session.myUserId + val myUserDisplayName = user?.toMatrixItem()?.getBestName() ?: session.myUserId val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) synchronized(eventList) { Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ") @@ -458,7 +460,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context if (eventList.isEmpty() || eventList.all { it.isRedacted }) { notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) - } else { + } else if (hasNewEvent) { // FIXME roomIdToEventMap.size is not correct, this is the number of rooms val nbEvents = roomIdToEventMap.size + simpleEvents.size val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index c575063ce9..14dfe5c6ee 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -53,6 +53,7 @@ import im.vector.app.core.utils.startNotificationChannelSettingsIntent import im.vector.app.features.call.VectorCallActivity import im.vector.app.features.call.service.CallHeadsUpActionReceiver import im.vector.app.features.call.webrtc.WebRtcCall +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailArgs @@ -543,36 +544,27 @@ class NotificationUtils @Inject constructor(private val context: Context, .setWhen(lastMessageTimestamp) // MESSAGING_STYLE sets title and content for API 16 and above devices. .setStyle(messageStyle) - // A category allows groups of notifications to be ranked and filtered – per user or system settings. // For example, alarm notifications should display before promo notifications, or message from known contact // that can be displayed in not disturb mode if white listed (the later will need compat28.x) .setCategory(NotificationCompat.CATEGORY_MESSAGE) - // ID of the corresponding shortcut, for conversation features under API 30+ .setShortcutId(roomInfo.roomId) - // Title for API < 16 devices. .setContentTitle(roomInfo.roomDisplayName) // Content for API < 16 devices. .setContentText(stringProvider.getString(R.string.notification_new_messages)) - // Number of new notifications for API <24 (M and below) devices. .setSubText(stringProvider.getQuantityString(R.plurals.room_new_messages_notification, messageStyle.messages.size, messageStyle.messages.size)) - // Auto-bundling is enabled for 4 or more notifications on API 24+ (N+) // devices and all Wear devices. But we want a custom grouping, so we specify the groupID // TODO Group should be current user display name .setGroup(stringProvider.getString(R.string.app_name)) - // In order to avoid notification making sound twice (due to the summary notification) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) - .setSmallIcon(smallIcon) - // Set primary color (important for Wear 2.0 Notifications). .setColor(accentColor) - // Sets priority for 25 and below. For 26 and above, 'priority' is deprecated for // 'importance' which is set in the NotificationChannel. The integers representing // 'priority' are different from 'importance', so make sure you don't mix them. @@ -597,10 +589,12 @@ class NotificationUtils @Inject constructor(private val context: Context, val markRoomReadPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), markRoomReadIntent, PendingIntent.FLAG_UPDATE_CURRENT) - addAction(NotificationCompat.Action( - R.drawable.ic_material_done_all_white, - stringProvider.getString(R.string.action_mark_room_read), - markRoomReadPendingIntent)) + NotificationCompat.Action.Builder(R.drawable.ic_material_done_all_white, + stringProvider.getString(R.string.action_mark_room_read), markRoomReadPendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build() + .let { addAction(it) } // Quick reply if (!roomInfo.hasSmartReplyError) { @@ -611,6 +605,8 @@ class NotificationUtils @Inject constructor(private val context: Context, NotificationCompat.Action.Builder(R.drawable.vector_notification_quick_reply, stringProvider.getString(R.string.action_quick_reply), replyPendingIntent) .addRemoteInput(remoteInput) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY) + .setShowsUserInterface(false) .build() .let { addAction(it) } } @@ -918,8 +914,8 @@ class NotificationUtils @Inject constructor(private val context: Context, // We cannot use NotificationManagerCompat here. val setting = context.getSystemService()!!.currentInterruptionFilter - return setting == NotificationManager.INTERRUPTION_FILTER_NONE - || setting == NotificationManager.INTERRUPTION_FILTER_ALARMS + return setting == NotificationManager.INTERRUPTION_FILTER_NONE || + setting == NotificationManager.INTERRUPTION_FILTER_ALARMS } private fun getActionText(@StringRes stringRes: Int, @AttrRes colorRes: Int): Spannable { diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index ecaeea1899..7469f44583 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -29,6 +29,7 @@ import io.reactivex.schedulers.Schedulers import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser +import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.util.Optional @@ -55,7 +56,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false ): Single { - if (deepLink == null) { + if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) { return Single.just(false) } return Single @@ -122,6 +123,13 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } + private fun isPermalinkSupported(context: Context, url: String): Boolean { + return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) || + context.resources.getStringArray(R.array.permalink_supported_hosts).any { + url.startsWith(it) + } + } + private fun PermalinkData.RoomLink.getRoomId(): Single> { val session = activeSessionHolder.getSafeActiveSession() return if (isRoomAlias && session != null) { @@ -179,6 +187,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } } + + companion object { + const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" + const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" + const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/" + } } interface NavigationInterceptor { diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt deleted file mode 100644 index ee4e0e05b5..0000000000 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.permalink - -import android.content.Intent -import android.os.Bundle -import im.vector.app.R -import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.ScreenComponent -import im.vector.app.core.extensions.replaceFragment -import im.vector.app.core.platform.VectorBaseActivity -import im.vector.app.databinding.FragmentProgressBinding -import im.vector.app.features.home.HomeActivity -import im.vector.app.features.home.LoadingFragment -import javax.inject.Inject - -class PermalinkHandlerActivity : VectorBaseActivity() { - - @Inject lateinit var permalinkHandler: PermalinkHandler - @Inject lateinit var sessionHolder: ActiveSessionHolder - - override fun getBinding() = FragmentProgressBinding.inflate(layoutInflater) - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_simple) - if (isFirstCreation()) { - replaceFragment(R.id.simpleFragmentContainer, LoadingFragment::class.java) - } - handleIntent() - } - - private fun handleIntent() { - // If we are not logged in, open login screen. - // In the future, we might want to relaunch the process after login. - if (!sessionHolder.hasActiveSession()) { - startLoginActivity() - return - } - // We forward intent to HomeActivity (singleTask) to avoid the dueling app problem - // https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances - intent.setClass(this, HomeActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - startActivity(intent) - - finish() - } - - override fun onNewIntent(intent: Intent?) { - super.onNewIntent(intent) - handleIntent() - } - - private fun startLoginActivity() { - navigator.openLogin( - context = this, - flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK - ) - finish() - } -} diff --git a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt index 6866afa0a6..a36e945699 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt @@ -18,8 +18,8 @@ package im.vector.app.features.pin import android.content.Context import android.content.Intent -import com.google.android.material.appbar.MaterialToolbar import com.airbnb.mvrx.MvRx +import com.google.android.material.appbar.MaterialToolbar import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable diff --git a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt index 99b0a93528..2309d42f60 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt @@ -36,8 +36,8 @@ import im.vector.app.databinding.FragmentPinBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.settings.VectorPreferences -import kotlinx.parcelize.Parcelize import kotlinx.coroutines.launch +import kotlinx.parcelize.Parcelize import javax.inject.Inject @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt b/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt index 17ad35f07a..3b7aa18ee9 100644 --- a/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt +++ b/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt @@ -22,6 +22,7 @@ import im.vector.app.R import im.vector.app.core.extensions.setLeftDrawable import im.vector.app.core.glide.GlideApp import im.vector.app.databinding.AlerterIncomingCallLayoutBinding +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/popup/JitsiCallAlert.kt b/vector/src/main/java/im/vector/app/features/popup/JitsiCallAlert.kt index 1c0ec65c36..00c429a621 100644 --- a/vector/src/main/java/im/vector/app/features/popup/JitsiCallAlert.kt +++ b/vector/src/main/java/im/vector/app/features/popup/JitsiCallAlert.kt @@ -21,6 +21,7 @@ import android.view.View import im.vector.app.R import im.vector.app.core.glide.GlideApp import im.vector.app.databinding.AlerterJitsiCallLayoutBinding +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt index 9842709f9e..9084c64a40 100644 --- a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt +++ b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt @@ -52,7 +52,7 @@ class PopupAlertManager @Inject constructor() { private val alertQueue = mutableListOf() - fun hasAlertsToShow() : Boolean { + fun hasAlertsToShow(): Boolean { return currentAlerter != null || alertQueue.isNotEmpty() } @@ -298,10 +298,10 @@ class PopupAlertManager @Inject constructor() { } private fun shouldBeDisplayedIn(alert: VectorAlert?, activity: Activity): Boolean { - return alert != null - && activity !is PinActivity - && activity !is SignedOutActivity - && activity is VectorBaseActivity<*> - && alert.shouldBeDisplayedIn.invoke(activity) + return alert != null && + activity !is PinActivity && + activity !is SignedOutActivity && + activity is VectorBaseActivity<*> && + alert.shouldBeDisplayedIn.invoke(activity) } } diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt index 1455a85edf..3a3841c026 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt @@ -21,12 +21,11 @@ import android.view.ViewGroup import com.google.zxing.Result import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentQrCodeScannerBinding - import me.dm7.barcodescanner.zxing.ZXingScannerView import javax.inject.Inject -class QrCodeScannerFragment @Inject constructor() - : VectorBaseFragment(), +class QrCodeScannerFragment @Inject constructor() : + VectorBaseFragment(), ZXingScannerView.ResultHandler { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerBinding { diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index 27adefd50f..89aa307dc4 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -30,7 +30,6 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBugReportBinding import org.matrix.android.sdk.api.extensions.tryOrNull - import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 9ae1d37f4d..5b3d194d33 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -267,8 +267,8 @@ class BugReporter @Inject constructor( .addFormDataPart("device", Build.MODEL.trim()) .addFormDataPart("verbose_log", vectorPreferences.labAllowedExtendedLogging().toOnOff()) .addFormDataPart("multi_window", inMultiWindowMode.toOnOff()) - .addFormDataPart("os", Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ") " - + Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME) + .addFormDataPart("os", Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ") " + + Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME) .addFormDataPart("locale", Locale.getDefault().toString()) .addFormDataPart("app_language", VectorLocale.applicationLocale.toString()) .addFormDataPart("default_app_language", systemLocaleProvider.getSystemLocale().toString()) diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt index 822f291e1f..bcc18a995a 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt @@ -23,7 +23,6 @@ import androidx.lifecycle.lifecycleScope import im.vector.app.core.extensions.cleanup import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.EmojiChooserFragmentBinding - import javax.inject.Inject class EmojiChooserFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index 7140bb0baa..e371aae096 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -38,7 +38,6 @@ import im.vector.app.databinding.ActivityEmojiReactionPickerBinding import im.vector.app.features.reactions.data.EmojiDataSource import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.launch - import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -165,6 +164,12 @@ class EmojiReactionPickerActivity : VectorBaseActivity Timber.e(err) } @@ -174,6 +179,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(initialState) { + private val dataSource: EmojiDataSource) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index 0f6f1620a8..c342d6519d 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -37,8 +37,8 @@ import javax.inject.Inject */ class ReactionButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) - : LinearLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { + defStyleAttr: Int = 0) : + LinearLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { init { if (context is HasScreenInjector) { diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt index c8b0037311..ece953a185 100644 --- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt @@ -22,8 +22,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import com.jakewharton.rxrelay2.BehaviorRelay import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -46,8 +46,8 @@ import org.matrix.android.sdk.rx.unwrap class RequireActiveMembershipViewModel @AssistedInject constructor( @Assisted initialState: RequireActiveMembershipViewState, private val stringProvider: StringProvider, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/ExplicitTermFilter.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/ExplicitTermFilter.kt index 0d1f55485c..e184e77557 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/ExplicitTermFilter.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/ExplicitTermFilter.kt @@ -39,8 +39,8 @@ class ExplicitTermFilter @Inject constructor( } fun isValid(str: String): Boolean { - return explicitContentRegex.matches(str.replace("\n", " ")).not() + return explicitContentRegex.matches(str.replace("\n", " ")).not() && // Special treatment for "18+" since word boundaries does not work here - && str.contains("18+").not() + str.contains("18+").not() } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt index 32c87bffd4..a350bff0bb 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt @@ -61,8 +61,8 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri unknownRoomItem?.addTo(this) - if ((viewState.hasMore && viewState.asyncPublicRoomsRequest is Success) - || viewState.asyncPublicRoomsRequest is Incomplete) { + if ((viewState.hasMore && viewState.asyncPublicRoomsRequest is Success) || + viewState.asyncPublicRoomsRequest is Incomplete) { loadingItem { // Change id to avoid list to scroll automatically when first results are displayed if (publicRooms.isEmpty()) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt index 8214b26fea..1ff8af1d7d 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt @@ -37,7 +37,6 @@ import im.vector.app.databinding.FragmentPublicRoomsBinding import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.PermalinkHandler import io.reactivex.rxkotlin.subscribeBy - import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index 9a63e81a2f..02bae82e03 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -28,8 +28,8 @@ import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.popBackstack import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding -import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs +import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt index 2676096b6b..7dd9cb4e00 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt @@ -29,6 +29,8 @@ import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formEditableAvatarItem import im.vector.app.features.form.formSubmitButtonItem import im.vector.app.features.form.formSwitchItem +import org.matrix.android.sdk.api.MatrixConstants +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import javax.inject.Inject @@ -140,6 +142,7 @@ class CreateRoomController @Inject constructor( value(viewState.aliasLocalPart) suffixText(":" + viewState.homeServerName) prefixText("#") + maxLength(MatrixConstants.maxAliasLocalPartLength(viewState.homeServerName)) hint(host.stringProvider.getString(R.string.room_alias_address_hint)) errorMessage( host.roomAliasErrorFormatter.format( @@ -165,7 +168,8 @@ class CreateRoomController @Inject constructor( host.stringProvider.getString(R.string.create_room_encryption_description) } ) - switchChecked(viewState.isEncrypted) + + switchChecked(viewState.isEncrypted ?: viewState.defaultEncrypted[viewState.roomJoinRules].orFalse()) listener { value -> host.listener?.setIsEncrypted(value) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index 70f041bd69..ac4c9db89f 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -163,8 +163,9 @@ class CreateRoomFragment @Inject constructor( } override fun selectVisibility() = withState(viewModel) { state -> - - val allowed = if (state.supportsRestricted) { + // If restricted is supported and the user is in the context of a parent space + // then show restricted option. + val allowed = if (state.supportsRestricted && state.parentSpaceId != null) { listOf(RoomJoinRules.INVITE, RoomJoinRules.PUBLIC, RoomJoinRules.RESTRICTED) } else { listOf(RoomJoinRules.INVITE, RoomJoinRules.PUBLIC) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt index 9a9812933b..14789aabb5 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt @@ -36,6 +36,7 @@ import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixPatterns.getDomain +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session @@ -55,7 +56,7 @@ import timber.log.Timber class CreateRoomViewModel @AssistedInject constructor(@Assisted private val initialState: CreateRoomViewState, private val session: Session, private val rawService: RawService, - private val vectorPreferences: VectorPreferences + vectorPreferences: VectorPreferences ) : VectorViewModel(initialState) { @AssistedFactory @@ -109,8 +110,13 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init setState { copy( - isEncrypted = RoomJoinRules.INVITE == roomJoinRules && adminE2EByDefault, - hsAdminHasDisabledE2E = !adminE2EByDefault + hsAdminHasDisabledE2E = !adminE2EByDefault, + defaultEncrypted = mapOf( + RoomJoinRules.INVITE to adminE2EByDefault, + RoomJoinRules.PUBLIC to false, + RoomJoinRules.RESTRICTED to adminE2EByDefault + ) + ) } } @@ -286,7 +292,12 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init disableFederation = state.disableFederation // Encryption - if (state.isEncrypted) { + val shouldEncrypt = when (state.roomJoinRules) { + // we ignore the isEncrypted for public room as the switch is hidden in this case + RoomJoinRules.PUBLIC -> false + else -> state.isEncrypted ?: state.defaultEncrypted[state.roomJoinRules].orFalse() + } + if (shouldEncrypt) { enableEncryption() } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt index db56a19904..46076edec6 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt @@ -28,7 +28,8 @@ data class CreateRoomViewState( val roomName: String = "", val roomTopic: String = "", val roomJoinRules: RoomJoinRules = RoomJoinRules.INVITE, - val isEncrypted: Boolean = false, + val isEncrypted: Boolean? = null, + val defaultEncrypted: Map = emptyMap(), val showAdvanced: Boolean = false, val disableFederation: Boolean = false, val homeServerName: String = "", @@ -50,8 +51,8 @@ data class CreateRoomViewState( /** * Return true if there is not important input from user */ - fun isEmpty() = avatarUri == null - && roomName.isEmpty() - && roomTopic.isEmpty() - && aliasLocalPart.isNullOrEmpty() + fun isEmpty() = avatarUri == null && + roomName.isEmpty() && + roomTopic.isEmpty() && + aliasLocalPart.isNullOrEmpty() } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateSubSpaceController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateSubSpaceController.kt index 6d292c85da..26ea2f30a3 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateSubSpaceController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateSubSpaceController.kt @@ -28,6 +28,7 @@ import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formEditableSquareAvatarItem import im.vector.app.features.form.formMultiLineEditTextItem import im.vector.app.features.form.formSubmitButtonItem +import org.matrix.android.sdk.api.MatrixConstants import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import javax.inject.Inject @@ -81,6 +82,7 @@ class CreateSubSpaceController @Inject constructor( hint(host.stringProvider.getString(R.string.create_space_alias_hint)) suffixText(":" + data.homeServerName) prefixText("#") + maxLength(MatrixConstants.maxAliasLocalPartLength(data.homeServerName)) errorMessage( host.roomAliasErrorFormatter.format( (((data.asyncCreateRoomRequest as? Fail)?.error) as? CreateRoomFailure.AliasError)?.aliasError) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt index d8db38609c..08e044630d 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt @@ -160,8 +160,8 @@ class RoomDirectoryPickerController @Inject constructor( } private fun getErrorMessage(error: Throwable): String { - return if (error is Failure.ServerError - && error.httpCode == HttpsURLConnection.HTTP_INTERNAL_ERROR /* 500 */) { + return if (error is Failure.ServerError && + error.httpCode == HttpsURLConnection.HTTP_INTERNAL_ERROR /* 500 */) { stringProvider.getString(R.string.directory_add_a_new_server_error) } else { errorFormatter.toHumanReadable(error) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index a559b0554d..04c4ea18bf 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -44,8 +44,8 @@ import org.matrix.android.sdk.rx.rx import timber.log.Timber class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val initialState: RoomPreviewViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt index 75286ea24f..7af6e757ad 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt @@ -62,7 +62,7 @@ data class RoomPreviewViewState( roomType = args.roomType ) - fun matrixItem() : MatrixItem { + fun matrixItem(): MatrixItem { return if (roomType == RoomType.SPACE) MatrixItem.SpaceItem(roomId, roomName ?: roomAlias, avatarUrl) else MatrixItem.RoomItem(roomId, roomName ?: roomAlias, avatarUrl) } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt index 37ad2741ca..72122ff7fe 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt @@ -20,9 +20,9 @@ package im.vector.app.features.roommemberprofile import android.content.Context import android.content.Intent import android.widget.Toast -import com.google.android.material.appbar.MaterialToolbar import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.viewModel +import com.google.android.material.appbar.MaterialToolbar import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index d8b4f249da..d8e967fd27 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -47,6 +47,7 @@ import im.vector.app.databinding.DialogShareQrCodeBinding import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.ViewStubRoomMemberProfileHeaderBinding import im.vector.app.features.crypto.verification.VerificationBottomSheet +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailPendingAction import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 4b57bdc6aa..dbddad87ca 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -26,12 +26,13 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.features.displayname.getBestName import im.vector.app.features.powerlevel.PowerLevelsObservableFactory import io.reactivex.Observable import io.reactivex.functions.BiFunction @@ -59,8 +60,8 @@ import org.matrix.android.sdk.rx.unwrap class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState, private val stringProvider: StringProvider, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index 7d31a5c811..386e0c98af 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -23,8 +23,8 @@ import com.airbnb.mvrx.MvRxState import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -46,8 +46,8 @@ data class DeviceListViewState( class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted private val initialState: DeviceListViewState, @Assisted private val args: DeviceListBottomSheet.Args, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt index ca2141ccd2..0325cb132e 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt @@ -39,8 +39,8 @@ import javax.inject.Inject class DeviceListEpoxyController @Inject constructor(private val stringProvider: StringProvider, private val colorProvider: ColorProvider, private val dimensionConverter: DimensionConverter, - private val vectorPreferences: VectorPreferences) - : TypedEpoxyController() { + private val vectorPreferences: VectorPreferences) : + TypedEpoxyController() { interface InteractionListener { fun onDeviceSelected(device: CryptoDeviceInfo) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt index fd770ca530..dbf1f19595 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.BottomSheetGenericListBinding - import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt index 65dfa75b65..f82ecb6ddf 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.BottomSheetGenericListBinding - import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt index b8711372af..bce219a711 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt @@ -34,8 +34,8 @@ import javax.inject.Inject class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider, private val colorProvider: ColorProvider, private val dimensionConverter: DimensionConverter, - private val vectorPreferences: VectorPreferences) - : TypedEpoxyController() { + private val vectorPreferences: VectorPreferences) : + TypedEpoxyController() { interface InteractionListener { fun onVerifyManually(device: CryptoDeviceInfo) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt index 9cd4bb87bd..e6b898c2b9 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt @@ -25,7 +25,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.databinding.DialogEditPowerLevelBinding - import org.matrix.android.sdk.api.session.room.powerlevels.Role object EditPowerLevelDialogs { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index d28878283f..ec9beda9d6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -20,9 +20,9 @@ package im.vector.app.features.roomprofile import android.content.Context import android.content.Intent import android.widget.Toast -import com.google.android.material.appbar.MaterialToolbar import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.viewModel +import com.google.android.material.appbar.MaterialToolbar import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment @@ -35,12 +35,12 @@ import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore import im.vector.app.features.room.RequireActiveMembershipViewEvents import im.vector.app.features.room.RequireActiveMembershipViewModel import im.vector.app.features.room.RequireActiveMembershipViewState +import im.vector.app.features.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment -import im.vector.app.features.roomprofile.settings.RoomSettingsFragment -import im.vector.app.features.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment +import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index be026894b6..b237faa17d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -94,11 +94,11 @@ class RoomProfileController @Inject constructor( // Upgrade warning val roomVersion = data.roomCreateContent()?.roomVersion - if (data.canUpgradeRoom - && !data.isTombstoned - && roomVersion != null - && data.isUsingUnstableRoomVersion - && data.recommendedRoomVersion != null) { + if (data.canUpgradeRoom && + !data.isTombstoned && + roomVersion != null && + data.isUsingUnstableRoomVersion && + data.recommendedRoomVersion != null) { genericFooterItem { id("version_warning") text(host.stringProvider.getString(R.string.room_using_unstable_room_version, roomVersion)) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt index a14bb61606..a1c252d356 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt @@ -36,6 +36,7 @@ import im.vector.app.features.discovery.settingsInfoItem import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formSwitchItem import im.vector.app.features.roomdirectory.createroom.RoomAliasErrorFormatter +import org.matrix.android.sdk.api.MatrixConstants import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomType @@ -174,6 +175,7 @@ class RoomAliasController @Inject constructor( formEditTextItem { id("publishManuallyEdit") value(data.publishManuallyState.value) + maxLength(MatrixConstants.ALIAS_MAX_LENGTH) hint(host.stringProvider.getString(R.string.room_alias_address_hint)) inputType(InputType.TYPE_CLASS_TEXT) onTextChange { text -> @@ -253,6 +255,7 @@ class RoomAliasController @Inject constructor( value(data.newLocalAliasState.value) suffixText(":" + data.homeServerName) prefixText("#") + maxLength(MatrixConstants.maxAliasLocalPartLength(data.homeServerName)) hint(host.stringProvider.getString(R.string.room_alias_address_hint)) errorMessage(host.roomAliasErrorFormatter.format((data.newLocalAliasState.asyncRequest as? Fail)?.error as? RoomAliasError)) onTextChange { value -> diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt index 36dbf7bf8c..0b144bea9f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt @@ -38,7 +38,6 @@ import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedAction import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel - import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.util.toMatrixItem diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt index aa9981997c..bb9a5c39d9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt @@ -43,8 +43,8 @@ import org.matrix.android.sdk.rx.rx import org.matrix.android.sdk.rx.unwrap class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: RoomAliasViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetSharedAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetSharedAction.kt index 13909c401f..d7cb923603 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetSharedAction.kt @@ -24,8 +24,8 @@ import im.vector.app.core.platform.VectorSharedAction sealed class RoomAliasBottomSheetSharedAction( @StringRes val titleRes: Int, @DrawableRes val iconResId: Int = 0, - val destructive: Boolean = false) - : VectorSharedAction { + val destructive: Boolean = false) : + VectorSharedAction { data class ShareAlias(val matrixTo: String) : RoomAliasBottomSheetSharedAction( R.string.share, diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt index e762b52025..2029491546 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt @@ -19,8 +19,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt index 807954438f..72f43639ed 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt @@ -34,7 +34,6 @@ import im.vector.app.core.utils.toast import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs - import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt index 1b64261fcb..b5c10ec2fa 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt @@ -21,8 +21,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -44,8 +44,8 @@ import org.matrix.android.sdk.rx.unwrap class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomBannedMemberListViewState, private val stringProvider: StringProvider, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt index b8d0842c22..4337e8767a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt @@ -34,7 +34,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomMemberListBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs - import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index 5c6ff48403..1e3a97a027 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -51,8 +51,8 @@ import timber.log.Timber class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomMemberListViewState, private val roomMemberSummaryComparator: RoomMemberSummaryComparator, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryFilter.kt index bd9fb7b941..449b8663d6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryFilter.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberSummaryFilter.kt @@ -31,9 +31,9 @@ class RoomMemberSummaryFilter @Inject constructor() : Predicate get() { - if ((roomSummary()?.isEncrypted == true && notificationState() == RoomNotificationState.MENTIONS_ONLY) - || notificationState() == RoomNotificationState.ALL_MESSAGES) { + if ((roomSummary()?.isEncrypted == true && notificationState() == RoomNotificationState.MENTIONS_ONLY) || + notificationState() == RoomNotificationState.ALL_MESSAGES) { /** if in an encrypted room, mentions notifications are not supported so show "All Messages" as selected. * Also in the new settings there is no notion of notifications without sound so it maps to noisy also */ @@ -49,6 +49,7 @@ val RoomNotificationSettingsViewState.notificationStateMapped: Async(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt index e872a04d80..5b0943906a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt @@ -47,8 +47,8 @@ import org.matrix.android.sdk.rx.unwrap class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, private val vectorPreferences: VectorPreferences, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { @@ -112,11 +112,11 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: val summary = asyncSummary() setState { copy( - showSaveAction = avatarAction !is RoomSettingsViewState.AvatarAction.None - || summary?.name != newName - || summary?.topic != newTopic - || (newHistoryVisibility != null && newHistoryVisibility != currentHistoryVisibility) - || newJoinRule.hasChanged() + showSaveAction = avatarAction !is RoomSettingsViewState.AvatarAction.None || + summary?.name != newName || + summary?.topic != newTopic || + (newHistoryVisibility != null && newHistoryVisibility != currentHistoryVisibility) || + newJoinRule.hasChanged() ) } } @@ -146,8 +146,8 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: canChangeHistoryVisibility = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_HISTORY_VISIBILITY), canChangeJoinRule = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, - EventType.STATE_ROOM_JOIN_RULES) - && powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, + EventType.STATE_ROOM_JOIN_RULES) && + powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_GUEST_ACCESS), canAddChildren = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilitySharedActionViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilitySharedActionViewModel.kt index 4f1bdca194..c4f4892984 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilitySharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilitySharedActionViewModel.kt @@ -19,5 +19,5 @@ package im.vector.app.features.roomprofile.settings.historyvisibility import im.vector.app.core.platform.VectorSharedActionViewModel import javax.inject.Inject -class RoomHistoryVisibilitySharedActionViewModel @Inject constructor() - : VectorSharedActionViewModel() +class RoomHistoryVisibilitySharedActionViewModel @Inject constructor() : + VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityViewModel.kt index c2a8ae967f..5580156918 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityViewModel.kt @@ -18,5 +18,5 @@ package im.vector.app.features.roomprofile.settings.historyvisibility import im.vector.app.core.ui.bottomsheet.BottomSheetGenericViewModel -class RoomHistoryVisibilityViewModel(initialState: RoomHistoryVisibilityState) - : BottomSheetGenericViewModel(initialState) +class RoomHistoryVisibilityViewModel(initialState: RoomHistoryVisibilityState) : + BottomSheetGenericViewModel(initialState) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleSharedActionViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleSharedActionViewModel.kt index a7df2cb475..971d71e0df 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleSharedActionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleSharedActionViewModel.kt @@ -19,5 +19,5 @@ package im.vector.app.features.roomprofile.settings.joinrule import im.vector.app.core.platform.VectorSharedActionViewModel import javax.inject.Inject -class RoomJoinRuleSharedActionViewModel @Inject constructor() - : VectorSharedActionViewModel() +class RoomJoinRuleSharedActionViewModel @Inject constructor() : + VectorSharedActionViewModel() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleViewModel.kt index 4305bfa72d..1ff374bf5b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleViewModel.kt @@ -18,5 +18,5 @@ package im.vector.app.features.roomprofile.settings.joinrule import im.vector.app.core.ui.bottomsheet.BottomSheetGenericViewModel -class RoomJoinRuleViewModel(initialState: RoomJoinRuleState) - : BottomSheetGenericViewModel(initialState) +class RoomJoinRuleViewModel(initialState: RoomJoinRuleState) : + BottomSheetGenericViewModel(initialState) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt index eaa435f853..9a9df700f8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt @@ -35,6 +35,7 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.styleMatchingText +import im.vector.app.features.displayname.getBestName import im.vector.app.features.roomprofile.settings.joinrule.toOption import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.launch @@ -78,9 +79,9 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( val unknownAllowedOrRooms = mutableListOf() initialAllowList.orEmpty().forEach { entry -> val summary = entry.roomId?.let { session.getRoomSummary(it) } - if (summary == null // it's not known by me - || summary.roomType != RoomType.SPACE // it's not a space - || !roomSummary.flattenParentIds.contains(summary.roomId) // it's not a parent space + if (summary == null || // it's not known by me + summary.roomType != RoomType.SPACE || // it's not a space + !roomSummary.flattenParentIds.contains(summary.roomId) // it's not a parent space ) { (summary?.toMatrixItem() ?: entry.roomId?.let { MatrixItem.RoomItem(it, null, null) })?.let { unknownAllowedOrRooms.add(it) @@ -104,8 +105,8 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( // server is not really checking that, just to be sure let's check val restrictedSupportedByThisVersion = homeServerCapabilities .isFeatureSupported(HomeServerCapabilities.ROOM_CAP_RESTRICTED, room.getRoomVersion()) - if (safeRule == RoomJoinRules.RESTRICTED - && !restrictedSupportedByThisVersion) { + if (safeRule == RoomJoinRules.RESTRICTED && + !restrictedSupportedByThisVersion) { safeRule = RoomJoinRules.INVITE } @@ -392,8 +393,7 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( companion object : MvRxViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: RoomJoinRuleChooseRestrictedState) - : RoomJoinRuleChooseRestrictedViewModel? { + override fun create(viewModelContext: ViewModelContext, state: RoomJoinRuleChooseRestrictedState): RoomJoinRuleChooseRestrictedViewModel? { val factory = when (viewModelContext) { is FragmentViewModelContext -> viewModelContext.fragment as? Factory is ActivityViewModelContext -> viewModelContext.activity as? Factory diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt index 2141b6bf27..f079daf262 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt @@ -38,7 +38,6 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.roomprofile.RoomProfileArgs import kotlinx.coroutines.launch - import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt index 1d6b056816..dfa3204d07 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt @@ -25,8 +25,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch @@ -91,8 +91,8 @@ class RoomUploadsViewModel @AssistedInject constructor( val groupedUploadEvents = result.uploadEvents .groupBy { - it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_IMAGE - || it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_VIDEO + it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_IMAGE || + it.contentWithAttachmentContent.msgType == MessageType.MSGTYPE_VIDEO } setState { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt index 972c606867..1739378761 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt @@ -35,7 +35,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericStateViewRecyclerBinding import im.vector.app.features.roomprofile.uploads.RoomUploadsAction import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel - import org.matrix.android.sdk.api.session.room.uploads.UploadEvent import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt index a7f7dbfe98..eb4337cffa 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt @@ -46,7 +46,6 @@ import im.vector.app.features.roomprofile.uploads.RoomUploadsAction import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState - import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.getFileUrl diff --git a/vector/src/main/java/im/vector/app/features/session/SessionListener.kt b/vector/src/main/java/im/vector/app/features/session/SessionListener.kt index d07e26d82d..c1ee0b527e 100644 --- a/vector/src/main/java/im/vector/app/features/session/SessionListener.kt +++ b/vector/src/main/java/im/vector/app/features/session/SessionListener.kt @@ -20,8 +20,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import im.vector.app.core.extensions.postLiveEvent import im.vector.app.core.utils.LiveEvent -import kotlinx.coroutines.cancelChildren import im.vector.app.features.call.vectorCallService +import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.launch import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 4341d381b6..07cd9d6dac 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -44,6 +44,7 @@ class VectorPreferences @Inject constructor(private val context: Context) { const val SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY = "SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY" const val SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY = "SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY" const val SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY = "SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY" + const val SETTINGS_DISCOVERY_PREFERENCE_KEY = "SETTINGS_DISCOVERY_PREFERENCE_KEY" const val SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY" const val SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY" @@ -932,8 +933,8 @@ class VectorPreferences @Inject constructor(private val context: Context) { * Return true if Pin code is disabled, or if user set the settings to see full notification content */ fun useCompleteNotificationFormat(): Boolean { - return !useFlagPinCode() - || defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG, true) + return !useFlagPinCode() || + defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG, true) } fun backgroundSyncTimeOut(): Int { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index caf42e7cf9..7cd4fc2d3d 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -15,8 +15,12 @@ */ package im.vector.app.features.settings +import android.app.Activity import android.content.Context import android.content.Intent +import android.os.Bundle +import android.os.Parcelable +import android.util.Log import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.preference.Preference @@ -27,15 +31,17 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityVectorSettingsBinding import im.vector.app.features.discovery.DiscoverySettingsFragment +import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment - import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session import timber.log.Timber import javax.inject.Inject +private const val KEY_ACTIVITY_PAYLOAD = "settings-activity-payload" + /** * Displays the client settings. */ @@ -65,27 +71,28 @@ class VectorSettingsActivity : VectorBaseActivity if (isFirstCreation()) { // display the fragment - when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) { - EXTRA_DIRECT_ACCESS_GENERAL -> + + when (val payload = readPayload(SettingsActivityPayload.Root)) { + SettingsActivityPayload.General -> replaceFragment(R.id.vector_settings_page, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG) - EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS -> + SettingsActivityPayload.AdvancedSettings -> replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG) - EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY -> + SettingsActivityPayload.SecurityPrivacy -> replaceFragment(R.id.vector_settings_page, VectorSettingsSecurityPrivacyFragment::class.java, null, FRAGMENT_TAG) - EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS -> + SettingsActivityPayload.SecurityPrivacyManageSessions -> replaceFragment(R.id.vector_settings_page, VectorSettingsDevicesFragment::class.java, null, FRAGMENT_TAG) - EXTRA_DIRECT_ACCESS_NOTIFICATIONS -> { + SettingsActivityPayload.Notifications -> { requestHighlightPreferenceKeyOnResume(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY) replaceFragment(R.id.vector_settings_page, VectorSettingsNotificationPreferenceFragment::class.java, null, FRAGMENT_TAG) } - EXTRA_DIRECT_ACCESS_DISCOVERY_SETTINGS -> { - replaceFragment(R.id.vector_settings_page, DiscoverySettingsFragment::class.java, null, FRAGMENT_TAG) + is SettingsActivityPayload.DiscoverySettings -> { + Log.e("!!!", "SettingsActivityPayload.DiscoverySettings : $payload") + replaceFragment(R.id.vector_settings_page, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG) } - - else -> + else -> replaceFragment(R.id.vector_settings_page, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG) } } @@ -149,19 +156,31 @@ class VectorSettingsActivity : VectorBaseActivity } } - fun navigateTo(fragmentClass: Class) { + fun navigateTo(fragmentClass: Class, arguments: Bundle? = null) { supportFragmentManager.beginTransaction() .setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out) - .replace(R.id.vector_settings_page, fragmentClass, null) + .replace(R.id.vector_settings_page, fragmentClass, arguments) .addToBackStack(null) .commit() } companion object { - fun getIntent(context: Context, directAccess: Int) = Intent(context, VectorSettingsActivity::class.java) - .apply { putExtra(EXTRA_DIRECT_ACCESS, directAccess) } + fun getIntent(context: Context, directAccess: Int) = Companion.getIntent(context, when (directAccess) { + EXTRA_DIRECT_ACCESS_ROOT -> SettingsActivityPayload.Root + EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS -> SettingsActivityPayload.AdvancedSettings + EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY -> SettingsActivityPayload.SecurityPrivacy + EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS -> SettingsActivityPayload.SecurityPrivacyManageSessions + EXTRA_DIRECT_ACCESS_GENERAL -> SettingsActivityPayload.General + EXTRA_DIRECT_ACCESS_NOTIFICATIONS -> SettingsActivityPayload.Notifications + EXTRA_DIRECT_ACCESS_DISCOVERY_SETTINGS -> SettingsActivityPayload.DiscoverySettings() + else -> { + Timber.w("Unknown directAccess: $directAccess defaulting to Root") + SettingsActivityPayload.Root + } + }) - private const val EXTRA_DIRECT_ACCESS = "EXTRA_DIRECT_ACCESS" + fun getIntent(context: Context, payload: SettingsActivityPayload) = Intent(context, VectorSettingsActivity::class.java) + .applyPayload(payload) const val EXTRA_DIRECT_ACCESS_ROOT = 0 const val EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS = 1 @@ -174,3 +193,11 @@ class VectorSettingsActivity : VectorBaseActivity private const val FRAGMENT_TAG = "VectorSettingsPreferencesFragment" } } + +private fun Activity.readPayload(default: T): T { + return intent.getParcelableExtra(KEY_ACTIVITY_PAYLOAD) ?: default +} + +private fun Intent.applyPayload(payload: T): Intent { + return putExtra(KEY_ACTIVITY_PAYLOAD, payload) +} diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index f40079c615..1be0bb3f76 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -38,6 +38,7 @@ import im.vector.app.R import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hidePassword +import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.core.preference.UserAvatarPreference @@ -50,6 +51,8 @@ import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogChangePasswordBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs +import im.vector.app.features.discovery.DiscoverySettingsFragment +import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.workers.signout.SignOutUiWorker import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.Dispatchers @@ -173,6 +176,19 @@ class VectorSettingsGeneralFragment @Inject constructor( mPasswordPreference.isVisible = false } + val openDiscoveryScreenPreferenceClickListener = Preference.OnPreferenceClickListener { + (requireActivity() as VectorSettingsActivity).navigateTo( + DiscoverySettingsFragment::class.java, + SettingsActivityPayload.DiscoverySettings().toMvRxBundle() + ) + true + } + + val discoveryPreference = findPreference(VectorPreferences.SETTINGS_DISCOVERY_PREFERENCE_KEY)!! + discoveryPreference.onPreferenceClickListener = openDiscoveryScreenPreferenceClickListener + + mIdentityServerPreference.onPreferenceClickListener = openDiscoveryScreenPreferenceClickListener + // Advanced settings // user account diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt index 212147e628..2a3ea799a5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt @@ -142,7 +142,7 @@ class VectorSettingsPreferencesFragment @Inject constructor( // Take photo or video updateTakePhotoOrVideoPreferenceSummary() takePhotoOrVideoPreference.onPreferenceClickListener = Preference.OnPreferenceClickListener { - PhotoOrVideoDialog(requireActivity(), vectorPreferences).showForSettings(object: PhotoOrVideoDialog.PhotoOrVideoDialogSettingsListener { + PhotoOrVideoDialog(requireActivity(), vectorPreferences).showForSettings(object : PhotoOrVideoDialog.PhotoOrVideoDialogSettingsListener { override fun onUpdated() { updateTakePhotoOrVideoPreferenceSummary() } diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountAction.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountAction.kt index bf62800d6a..0662afc700 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountAction.kt @@ -21,7 +21,7 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class DeactivateAccountAction : VectorViewModelAction { data class DeactivateAccount(val eraseAllData: Boolean) : DeactivateAccountAction() - object SsoAuthDone: DeactivateAccountAction() - data class PasswordAuthDone(val password: String): DeactivateAccountAction() - object ReAuthCancelled: DeactivateAccountAction() + object SsoAuthDone : DeactivateAccountAction() + data class PasswordAuthDone(val password: String) : DeactivateAccountAction() + object ReAuthCancelled : DeactivateAccountAction() } diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt index 2cc80bfa23..4e599e81fb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt @@ -34,7 +34,6 @@ import im.vector.app.features.MainActivityArgs import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.settings.VectorSettingsActivity import org.matrix.android.sdk.api.auth.data.LoginFlowTypes - import javax.inject.Inject class DeactivateAccountFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt index 80c64220c0..91c6223505 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt @@ -27,14 +27,14 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.auth.ReAuthActivity import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.auth.UserPasswordAuth +import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.failure.isInvalidUIAAuth import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.api.auth.UIABaseAuth -import org.matrix.android.sdk.api.auth.UserPasswordAuth import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -45,8 +45,8 @@ data class DeactivateAccountViewState( ) : MvRxState class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private val initialState: DeactivateAccountViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsAction.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsAction.kt index 735c456ff9..6c2fc7ecc2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsAction.kt @@ -19,8 +19,8 @@ package im.vector.app.features.settings.crosssigning import im.vector.app.core.platform.VectorViewModelAction sealed class CrossSigningSettingsAction : VectorViewModelAction { - object InitializeCrossSigning: CrossSigningSettingsAction() - object SsoAuthDone: CrossSigningSettingsAction() - data class PasswordAuthDone(val password: String): CrossSigningSettingsAction() - object ReAuthCancelled: CrossSigningSettingsAction() + object InitializeCrossSigning : CrossSigningSettingsAction() + object SsoAuthDone : CrossSigningSettingsAction() + data class PasswordAuthDone(val password: String) : CrossSigningSettingsAction() + object ReAuthCancelled : CrossSigningSettingsAction() } diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt index 17fbc333b5..d60d9138d7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt @@ -35,7 +35,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.auth.ReAuthActivity import org.matrix.android.sdk.api.auth.data.LoginFlowTypes - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt index 8bdf97b6ec..1bd498d1ab 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt @@ -102,8 +102,8 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( errCode: String?, promise: Continuation) { Timber.d("## UIA : initializeCrossSigning UIA") - if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD - && reAuthHelper.data != null && errCode == null) { + if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && + reAuthHelper.data != null && errCode == null) { UserPasswordAuth( session = null, user = session.myUserId, diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index d6ef31abf2..c109920cd6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -33,8 +33,8 @@ import javax.inject.Inject class DeviceVerificationInfoBottomSheetController @Inject constructor( private val stringProvider: StringProvider, - private val colorProvider: ColorProvider) - : TypedEpoxyController() { + private val colorProvider: ColorProvider) : + TypedEpoxyController() { var callback: Callback? = null diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index ee5b0a6092..5f903cf49d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -20,8 +20,8 @@ import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -91,8 +91,8 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As companion object : MvRxViewModelFactory { @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState) - : DeviceVerificationInfoBottomSheetViewModel? { + override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState): + DeviceVerificationInfoBottomSheetViewModel? { val fragment: DeviceVerificationInfoBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() val args = viewModelContext.args() return fragment.deviceVerificationInfoViewModelFactory.create(state, args.deviceId) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt index 46a476c270..e402982d97 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt @@ -22,6 +22,7 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo sealed class DevicesAction : VectorViewModelAction { object Refresh : DevicesAction() data class Delete(val deviceId: String) : DevicesAction() + // data class Password(val password: String) : DevicesAction() data class Rename(val deviceId: String, val newName: String) : DevicesAction() @@ -31,7 +32,7 @@ sealed class DevicesAction : VectorViewModelAction { object CompleteSecurity : DevicesAction() data class MarkAsManuallyVerified(val cryptoDeviceInfo: CryptoDeviceInfo) : DevicesAction() - object SsoAuthDone: DevicesAction() - data class PasswordAuthDone(val password: String): DevicesAction() - object ReAuthCancelled: DevicesAction() + object SsoAuthDone : DevicesAction() + data class PasswordAuthDone(val password: String) : DevicesAction() + object ReAuthCancelled : DevicesAction() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt index 8535c698a7..9e1f83582f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt @@ -18,8 +18,8 @@ package im.vector.app.features.settings.devices import im.vector.app.core.platform.VectorViewEvents -import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo @@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo */ sealed class DevicesViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : DevicesViewEvents() + // object HideLoading : DevicesViewEvents() data class Failure(val throwable: Throwable) : DevicesViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index c48b08e806..30342dbf2a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -40,23 +40,23 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse -import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.api.auth.UIABaseAuth -import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.android.sdk.rx.rx import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index 5af886b265..62923d4f3d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -40,7 +40,6 @@ import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.crypto.verification.VerificationBottomSheet import org.matrix.android.sdk.api.auth.data.LoginFlowTypes - import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt index a55032e44a..570da6875a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt @@ -31,7 +31,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.createJSonViewerStyleProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding - import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.internal.di.MoshiProvider diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt index d50caea579..7e5d690d8e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt @@ -24,8 +24,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -39,8 +39,8 @@ data class AccountDataViewState( ) : MvRxState class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: AccountDataViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { init { session.rx().liveUserAccountData(emptySet()) diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt index 6a0b13fe87..7325288c55 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt @@ -29,7 +29,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.createJSonViewerStyleProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding - import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.matrix.android.sdk.api.session.events.model.Event import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt index 325538ee5e..6d95255e70 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt @@ -25,8 +25,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -39,8 +39,8 @@ data class GossipingEventsPaperTrailState( ) : MvRxState class GossipingEventsPaperTrailViewModel @AssistedInject constructor(@Assisted initialState: GossipingEventsPaperTrailState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { init { refresh() diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt index 91e770babf..8bf89d975c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding - import javax.inject.Inject class IncomingKeyRequestListFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt index c0a791233f..88cae8fac2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt @@ -25,8 +25,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -42,8 +42,8 @@ data class KeyRequestListViewState( ) : MvRxState class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState: KeyRequestListViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { init { refresh() diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt index e7a56ef9df..f51c90ec5f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt @@ -28,8 +28,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewModel @@ -52,8 +52,8 @@ data class KeyRequestViewState( class KeyRequestViewModel @AssistedInject constructor( @Assisted initialState: KeyRequestViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt index 7bee0e283c..0b3d8812f1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt @@ -38,7 +38,6 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.selectTxtFileToWrite import im.vector.app.databinding.FragmentDevtoolKeyrequestsBinding - import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt index 77cddfff8c..0cbca2f38a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding - import javax.inject.Inject class OutgoingKeyRequestListFragment @Inject constructor( val viewModelFactory: KeyRequestListViewModel.Factory, diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index aa00f71542..6238885528 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -27,8 +27,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModelAction import kotlinx.coroutines.launch @@ -46,8 +46,8 @@ sealed class IgnoredUsersAction : VectorViewModelAction { } class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index fe09008cdd..1526ac0e69 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -33,7 +33,6 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding - import javax.inject.Inject class VectorSettingsIgnoredUsersFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt index 45fa6b735f..7368bec397 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt @@ -30,7 +30,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.restart import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentLocalePickerBinding - import java.util.Locale import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt index 2e59b0ef7d..d0077eec66 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt @@ -23,8 +23,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.configuration.VectorConfiguration diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt index 29d316bb76..793b94db1d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/NotificationIndex.kt @@ -44,11 +44,11 @@ val PushRule.notificationIndex: NotificationIndex? get() = */ private fun ruleMatches(rule: PushRule, targetRule: PushRule): Boolean { // Rules match if both are disabled, or if both are enabled and their highlight/sound/notify actions match up. - return (!rule.enabled && !targetRule.enabled) - || (rule.enabled - && targetRule.enabled - && rule.getHighlight() == targetRule.getHighlight() - && rule.getNotificationSound() == targetRule.getNotificationSound() - && rule.shouldNotify() == targetRule.shouldNotify() - && rule.shouldNotNotify() == targetRule.shouldNotNotify()) + return (!rule.enabled && !targetRule.enabled) || + (rule.enabled && + targetRule.enabled && + rule.getHighlight() == targetRule.getHighlight() && + rule.getNotificationSound() == targetRule.getNotificationSound() && + rule.shouldNotify() == targetRule.shouldNotify() && + rule.shouldNotNotify() == targetRule.shouldNotNotify()) } diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt index 93a788f528..3b4aef929d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsAdvancedNotificationPreferenceFragment.kt @@ -27,8 +27,8 @@ import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind import javax.inject.Inject -class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() - : VectorSettingsBaseFragment() { +class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() : + VectorSettingsBaseFragment() { override var titleRes: Int = R.string.settings_notification_advanced diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt index 3fc6293e6b..840e8ccde0 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt @@ -20,8 +20,8 @@ import im.vector.app.R import im.vector.app.core.preference.VectorPreferenceCategory import org.matrix.android.sdk.api.pushrules.RuleIds -class VectorSettingsDefaultNotificationPreferenceFragment - : VectorSettingsPushRuleNotificationPreferenceFragment() { +class VectorSettingsDefaultNotificationPreferenceFragment : + VectorSettingsPushRuleNotificationPreferenceFragment() { override var titleRes: Int = R.string.settings_notification_default diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index 59ed727191..fb1a357c30 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -33,8 +33,8 @@ import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.toJson -class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment - : VectorSettingsPushRuleNotificationPreferenceFragment() { +class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment : + VectorSettingsPushRuleNotificationPreferenceFragment() { override var titleRes: Int = R.string.settings_notification_mentions_and_keywords @@ -88,7 +88,7 @@ class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment false } - editKeywordPreference.listener = object: KeywordPreference.Listener { + editKeywordPreference.listener = object : KeywordPreference.Listener { override fun onFocusDidChange(hasFocus: Boolean) { keywordsHasFocus = true } diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt index 6e47079afa..1a830dc0c1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationsTroubleshootFragment.kt @@ -40,7 +40,6 @@ import im.vector.app.features.settings.VectorSettingsFragmentInteractionListener import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.app.features.settings.troubleshoot.TroubleshootTest import im.vector.app.push.fcm.NotificationTroubleshootTestManagerFactory - import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt index 2e083a7d65..71f8f0920a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsOtherNotificationPreferenceFragment.kt @@ -20,8 +20,8 @@ import im.vector.app.R import im.vector.app.core.preference.VectorPreferenceCategory import org.matrix.android.sdk.api.pushrules.RuleIds -class VectorSettingsOtherNotificationPreferenceFragment - : VectorSettingsPushRuleNotificationPreferenceFragment() { +class VectorSettingsOtherNotificationPreferenceFragment : + VectorSettingsPushRuleNotificationPreferenceFragment() { override var titleRes: Int = R.string.settings_notification_other diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt index dbf33f8fb3..26ee2fc601 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsPushRuleNotificationPreferenceFragment.kt @@ -24,8 +24,8 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind -abstract class VectorSettingsPushRuleNotificationPreferenceFragment - : VectorSettingsBaseFragment() { +abstract class VectorSettingsPushRuleNotificationPreferenceFragment : + VectorSettingsBaseFragment() { abstract val prefKeyToPushRuleId: Map diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayViewEvents.kt index 8b2a833b5c..380a5df876 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewayViewEvents.kt @@ -19,5 +19,5 @@ package im.vector.app.features.settings.push import im.vector.app.core.platform.VectorViewEvents sealed class PushGatewayViewEvents : VectorViewEvents { - data class RemovePusherFailed(val cause: Throwable): PushGatewayViewEvents() + data class RemovePusherFailed(val cause: Throwable) : PushGatewayViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt index cd1899741f..0801e78197 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt @@ -32,7 +32,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding import org.matrix.android.sdk.api.session.pushers.Pusher - import javax.inject.Inject // Referenced in vector_settings_notifications.xml diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt index 9a47fa2a15..bcfb68387b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt @@ -24,8 +24,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch @@ -38,8 +38,8 @@ data class PushGatewayViewState( ) : MvRxState class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState: PushGatewayViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt index d9dbdcc8d2..666f27272b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt @@ -27,7 +27,6 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding - import javax.inject.Inject // Referenced in vector_settings_notifications.xml diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt index 64ddc275eb..645ddbb8f7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt @@ -28,8 +28,8 @@ data class PushRulesViewState( val rules: List = emptyList() ) : MvRxState -class PushRulesViewModel(initialState: PushRulesViewState) - : VectorViewModel(initialState) { +class PushRulesViewModel(initialState: PushRulesViewState) : + VectorViewModel(initialState) { companion object : MvRxViewModelFactory { diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt index f9cf3bf5a3..cdc40185aa 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt @@ -295,9 +295,9 @@ class ThreePidsSettingsController @Inject constructor( val failure = (data.msisdnValidationRequests[threePid.value] as? Fail)?.error ?: return null // Wrong code? // See https://github.com/matrix-org/synapse/issues/8218 - return if (failure is Failure.ServerError - && failure.httpCode == 400 - && failure.error.code == MatrixError.M_UNKNOWN) { + return if (failure is Failure.ServerError && + failure.httpCode == 400 && + failure.error.code == MatrixError.M_UNKNOWN) { stringProvider.getString(R.string.settings_text_message_sent_wrong_code) } else { errorFormatter.toHumanReadable(failure) diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewEvents.kt index 0346fd137e..94ea8d24c6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewEvents.kt @@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse sealed class ThreePidsSettingsViewEvents : VectorViewEvents { data class Failure(val throwable: Throwable) : ThreePidsSettingsViewEvents() + // object RequestPassword : ThreePidsSettingsViewEvents() data class RequestReAuth(val registrationFlowResponse: RegistrationFlowResponse, val lastErrorCode: String?) : ThreePidsSettingsViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt index ac565e72a1..358436a7fc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt @@ -33,14 +33,14 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.ReadOnceTrue import im.vector.app.features.auth.ReAuthActivity import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.api.auth.UIABaseAuth -import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.rx.rx import timber.log.Timber import kotlin.coroutines.Continuation diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt index 70e5bdff10..8f0b2cfe74 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt @@ -24,8 +24,8 @@ import im.vector.app.R import im.vector.app.databinding.ItemNotificationTroubleshootBinding import im.vector.app.features.themes.ThemeUtils -class NotificationTroubleshootRecyclerViewAdapter(val tests: ArrayList) - : RecyclerView.Adapter() { +class NotificationTroubleshootRecyclerViewAdapter(val tests: ArrayList) : + RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestAccountSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestAccountSettings.kt index dad35fd13f..9d06e1724c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestAccountSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestAccountSettings.kt @@ -33,8 +33,8 @@ import javax.inject.Inject * Check that the main pushRule (RULE_ID_DISABLE_ALL) is correctly setup */ class TestAccountSettings @Inject constructor(private val stringProvider: StringProvider, - private val activeSessionHolder: ActiveSessionHolder) - : TroubleshootTest(R.string.settings_troubleshoot_test_account_settings_title) { + private val activeSessionHolder: ActiveSessionHolder) : + TroubleshootTest(R.string.settings_troubleshoot_test_account_settings_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { val session = activeSessionHolder.getSafeActiveSession() ?: return diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestDeviceSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestDeviceSettings.kt index 0d661e8b16..f9fc7e80e3 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestDeviceSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestDeviceSettings.kt @@ -26,8 +26,8 @@ import javax.inject.Inject * Checks if notifications are enable in the system settings for this app. */ class TestDeviceSettings @Inject constructor(private val vectorPreferences: VectorPreferences, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_device_settings_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_device_settings_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { if (vectorPreferences.areNotificationEnabledForDevice()) { diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestNotification.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestNotification.kt index 6f25ecfe39..412916c201 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestNotification.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestNotification.kt @@ -29,8 +29,8 @@ import javax.inject.Inject */ class TestNotification @Inject constructor(private val context: Context, private val notificationUtils: NotificationUtils, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_notification_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_notification_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { // Display the notification right now diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt index eea5705b7a..79e4377a5c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestPushRulesSettings.kt @@ -26,8 +26,8 @@ import org.matrix.android.sdk.api.pushrules.getActions import javax.inject.Inject class TestPushRulesSettings @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_bing_settings_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_bing_settings_title) { private val testedRules = listOf(RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt index ee652288be..d4f089b943 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt @@ -28,8 +28,8 @@ import javax.inject.Inject * Checks if notifications are enable in the system settings for this app. */ class TestSystemSettings @Inject constructor(private val context: Context, - private val stringProvider: StringProvider) - : TroubleshootTest(R.string.settings_troubleshoot_test_system_settings_title) { + private val stringProvider: StringProvider) : + TroubleshootTest(R.string.settings_troubleshoot_test_system_settings_title) { override fun perform(activityResultLauncher: ActivityResultLauncher) { if (NotificationManagerCompat.from(context).areNotificationsEnabled()) { @@ -40,7 +40,6 @@ class TestSystemSettings @Inject constructor(private val context: Context, description = stringProvider.getString(R.string.settings_troubleshoot_test_system_settings_failed) quickFix = object : TroubleshootQuickFix(R.string.open_settings) { override fun doFix() { - if (manager?.diagStatus == TestStatus.RUNNING) return // wait before all is finished startNotificationSettingsIntent(context, activityResultLauncher) } } diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt index 313bf2d2b7..2132ba7989 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt @@ -41,7 +41,6 @@ import im.vector.app.databinding.FragmentIncomingShareBinding import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs - import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt index 4d211d11de..da1b20b4d1 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt @@ -21,8 +21,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import com.jakewharton.rxrelay2.BehaviorRelay import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.toggle import im.vector.app.core.platform.VectorViewModel @@ -40,8 +40,8 @@ import java.util.concurrent.TimeUnit class IncomingShareViewModel @AssistedInject constructor( @Assisted initialState: IncomingShareViewState, private val session: Session, - private val breadcrumbsRoomComparator: BreadcrumbsRoomComparator) - : VectorViewModel(initialState) { + private val breadcrumbsRoomComparator: BreadcrumbsRoomComparator) : + VectorViewModel(initialState) { @AssistedFactory interface Factory { diff --git a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt index 08bd84994b..6f05a73f13 100644 --- a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt @@ -23,7 +23,6 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySignedOutBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs - import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 8c725cd81a..72b9a278e2 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -30,7 +30,6 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.login.LoginActivity - import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt index 5db82c0631..3689bff0c7 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -30,7 +30,6 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.login2.LoginActivity2 - import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt index 48cf7b12bc..2aa7f15172 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt @@ -32,7 +32,6 @@ import im.vector.app.features.login.AbstractLoginFragment import im.vector.app.features.login.LoginAction import im.vector.app.features.login.LoginMode import im.vector.app.features.login.LoginViewEvents - import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index f49527bd1d..552d279fad 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -103,11 +103,11 @@ class SoftLogoutViewModel @AssistedInject constructor( val loginMode = when { // SSO login is taken first - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) - && data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password - else -> LoginMode.Unsupported + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) && + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) + data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password + else -> LoginMode.Unsupported } setState { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt index ccc186aba7..4beb47c4a4 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt @@ -35,8 +35,8 @@ data class SoftLogoutViewState( ) : MvRxState { fun isLoading(): Boolean { - return asyncLoginAction is Loading + return asyncLoginAction is Loading || // Keep loading when it is success because of the delay to switch to the next Activity - || asyncLoginAction is Success + asyncLoginAction is Success } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt index bc2a9c604b..cf7871bc99 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt @@ -89,8 +89,7 @@ class InviteRoomSpaceChooserBottomSheet : VectorBaseBottomSheetDialogFragment(), SpaceD val sharedViewModel: SpaceDirectoryViewModel by viewModel() private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() { - override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) { + override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { if (f is MatrixToBottomSheet) { f.interactionListener = this@SpaceExploreActivity } - super.onFragmentAttached(fm, f, context) + super.onFragmentResumed(fm, f) } - override fun onFragmentDetached(fm: FragmentManager, f: Fragment) { + override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { if (f is MatrixToBottomSheet) { f.interactionListener = null } - super.onFragmentDetached(fm, f) + super.onFragmentPaused(fm, f) } } @@ -86,14 +87,14 @@ class SpaceExploreActivity : VectorBaseActivity(), SpaceD sharedViewModel.observeViewEvents { when (it) { - SpaceDirectoryViewEvents.Dismiss -> { + SpaceDirectoryViewEvents.Dismiss -> { finish() } - is SpaceDirectoryViewEvents.NavigateToRoom -> { + is SpaceDirectoryViewEvents.NavigateToRoom -> { navigator.openRoom(this, it.roomId) } is SpaceDirectoryViewEvents.NavigateToMxToBottomSheet -> { - MatrixToBottomSheet.withLink(it.link, this).show(supportFragmentManager, "ShowChild") + MatrixToBottomSheet.withLink(it.link).show(supportFragmentManager, "ShowChild") } } } @@ -115,7 +116,11 @@ class SpaceExploreActivity : VectorBaseActivity(), SpaceD override fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel = spaceDirectoryViewModelFactory.create(initialState) - override fun navigateToRoom(roomId: String) { + override fun mxToBottomSheetNavigateToRoom(roomId: String) { navigator.openRoom(this, roomId) } + + override fun mxToBottomSheetSwitchToSpace(spaceId: String) { + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt index 12d4b40f42..5bff2b733f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListAction.kt @@ -26,7 +26,7 @@ sealed class SpaceListAction : VectorViewModelAction { data class LeaveSpace(val spaceSummary: RoomSummary) : SpaceListAction() data class ToggleExpand(val spaceSummary: RoomSummary) : SpaceListAction() object AddSpace : SpaceListAction() - data class MoveSpace(val spaceId: String, val delta : Int) : SpaceListAction() + data class MoveSpace(val spaceId: String, val delta: Int) : SpaceListAction() data class OnStartDragging(val spaceId: String, val expanded: Boolean) : SpaceListAction() data class OnEndDragging(val spaceId: String, val expanded: Boolean) : SpaceListAction() diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt index 7482f4881e..795713152a 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewState.kt @@ -26,7 +26,7 @@ import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotification import org.matrix.android.sdk.api.util.MatrixItem data class SpaceListViewState( - val myMxItem : Async = Uninitialized, + val myMxItem: Async = Uninitialized, val asyncSpaces: Async> = Uninitialized, val selectedGroupingMethod: RoomGroupingMethod = RoomGroupingMethod.BySpace(null), val rootSpacesOrdered: List? = null, @@ -34,5 +34,5 @@ data class SpaceListViewState( val spaceOrderLocalEchos: Map? = null, val legacyGroups: List? = null, val expandedStates: Map = emptyMap(), - val homeAggregateCount : RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0) + val homeAggregateCount: RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0) ) : MvRxState diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt index 828308007b..d9d4058534 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt @@ -84,8 +84,8 @@ class SpaceSummaryController @Inject constructor( avatarRenderer(host.avatarRenderer) id("all_communities") matrixItem(mxItem.copy(displayName = host.stringProvider.getString(R.string.group_all_communities))) - selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup - && nonNullViewState.selectedGroupingMethod.group() == null) + selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup && + nonNullViewState.selectedGroupingMethod.group() == null) listener { host.callback?.onGroupSelected(null) } } } @@ -95,8 +95,8 @@ class SpaceSummaryController @Inject constructor( avatarRenderer(host.avatarRenderer) id(groupSummary.groupId) matrixItem(groupSummary.toMatrixItem()) - selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup - && nonNullViewState.selectedGroupingMethod.group()?.groupId == groupSummary.groupId) + selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup && + nonNullViewState.selectedGroupingMethod.group()?.groupId == groupSummary.groupId) listener { host.callback?.onGroupSelected(groupSummary) } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceState.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceState.kt index 6fb5853269..ab7fb0cc25 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceState.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceState.kt @@ -28,7 +28,7 @@ data class CreateSpaceState( val step: Step = Step.ChooseType, val spaceType: SpaceType? = null, val spaceTopology: SpaceTopology? = null, - val homeServerName: String? = null, + val homeServerName: String = "", val aliasLocalPart: String? = null, val aliasManuallyModified: Boolean = false, val aliasVerificationTask: Async = Uninitialized, diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt index e6ead2294e..4495ee31a1 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt @@ -134,7 +134,7 @@ class CreateSpaceViewModel @AssistedInject constructor( ) } else { val tentativeAlias = - MatrixPatterns.candidateAliasFromRoomName(action.name) + MatrixPatterns.candidateAliasFromRoomName(action.name, homeServerName) copy( nameInlineError = null, name = action.name, diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt index f6f168c365..00b4b64296 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModelTask.kt @@ -35,7 +35,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset import org.matrix.android.sdk.api.session.room.model.create.RestrictedRoomPreset - import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.session.space.CreateSpaceParams import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt index 27c08d1f6f..14b0db2cd1 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt @@ -27,6 +27,7 @@ import im.vector.app.features.form.formEditableSquareAvatarItem import im.vector.app.features.form.formMultiLineEditTextItem import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomdirectory.createroom.RoomAliasErrorFormatter +import org.matrix.android.sdk.api.MatrixConstants import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject @@ -94,6 +95,7 @@ class SpaceDetailEpoxyController @Inject constructor( hint(host.stringProvider.getString(R.string.create_space_alias_hint)) suffixText(":" + data.homeServerName) prefixText("#") + maxLength(MatrixConstants.maxAliasLocalPartLength(data.homeServerName)) onFocusChange { hasFocus -> host.aliasTextIsFocused = hasFocus } diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/WizardButtonView.kt b/vector/src/main/java/im/vector/app/features/spaces/create/WizardButtonView.kt index fc06ac4f7e..971d61dd9c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/WizardButtonView.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/WizardButtonView.kt @@ -29,8 +29,8 @@ import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.databinding.ViewSpaceTypeButtonBinding -class WizardButtonView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : ConstraintLayout(context, attrs, defStyle) { +class WizardButtonView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + ConstraintLayout(context, attrs, defStyle) { private val views: ViewSpaceTypeButtonBinding diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt index 28c06d84d1..4f8d0b6c2f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt @@ -36,6 +36,7 @@ import im.vector.app.core.platform.ButtonStateView import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.utils.toast import im.vector.app.databinding.BottomSheetInvitedToSpaceBinding +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.matrixto.SpaceCardRenderer import kotlinx.parcelize.Parcelize @@ -175,8 +176,7 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment { } // if filter is "Jo Do", it should match "John Doe" return filter.split(" ").all { - spaceChildInfo.name?.contains(it, ignoreCase = true).orFalse() - || spaceChildInfo.topic?.contains(it, ignoreCase = true).orFalse() + spaceChildInfo.name?.contains(it, ignoreCase = true).orFalse() || + spaceChildInfo.topic?.contains(it, ignoreCase = true).orFalse() } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewEvents.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewEvents.kt index 2f0eddb189..8f85008c97 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewEvents.kt @@ -19,7 +19,7 @@ package im.vector.app.features.spaces.preview import im.vector.app.core.platform.VectorViewEvents sealed class SpacePreviewViewEvents : VectorViewEvents { - object Dismiss: SpacePreviewViewEvents() - object JoinSuccess: SpacePreviewViewEvents() - data class JoinFailure(val message: String?): SpacePreviewViewEvents() + object Dismiss : SpacePreviewViewEvents() + object JoinSuccess : SpacePreviewViewEvents() + data class JoinFailure(val message: String?) : SpacePreviewViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpaceTabView.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpaceTabView.kt index 675e7070e7..41fc8bf6b9 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpaceTabView.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpaceTabView.kt @@ -23,8 +23,8 @@ import im.vector.app.R class SpaceTabView constructor(context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) - : LinearLayout(context, attrs, defStyleAttr) { + defStyleAttr: Int = 0) : + LinearLayout(context, attrs, defStyleAttr) { constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) {} constructor(context: Context) : this(context, null, 0) {} diff --git a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt index 63a0f980a9..ce6df67d53 100755 --- a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt +++ b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt @@ -27,8 +27,8 @@ import im.vector.app.databinding.ViewSyncStateBinding import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.sync.SyncState -class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) - : LinearLayout(context, attrs, defStyle) { +class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : + LinearLayout(context, attrs, defStyle) { private val views: ViewSyncStateBinding diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt index 7a97cbf8cd..cb76e5b31f 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt @@ -33,7 +33,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.openUrlInChromeCustomTab import im.vector.app.databinding.FragmentReviewTermsBinding - import org.matrix.android.sdk.api.session.terms.TermsService import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt index 4ecad80876..db9e017473 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt @@ -23,8 +23,8 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index c4c9ca63ae..6c8ea0a3f9 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -71,8 +71,8 @@ object ThemeUtils { */ fun isLightTheme(context: Context): Boolean { val theme = getApplicationTheme(context) - return theme == THEME_LIGHT_VALUE - || (theme == SYSTEM_THEME_VALUE && !isSystemDarkTheme(context.resources)) + return theme == THEME_LIGHT_VALUE || + (theme == SYSTEM_THEME_VALUE && !isSystemDarkTheme(context.resources)) } /** diff --git a/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt b/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt index da9c6792ff..e70ffd0d76 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt @@ -37,13 +37,12 @@ import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.FragmentQrCodeScannerWithButtonBinding import im.vector.lib.multipicker.MultiPicker import im.vector.lib.multipicker.utils.ImageUtils - import me.dm7.barcodescanner.zxing.ZXingScannerView import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject -class ScanUserCodeFragment @Inject constructor() - : VectorBaseFragment(), +class ScanUserCodeFragment @Inject constructor() : + VectorBaseFragment(), ZXingScannerView.ResultHandler { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerWithButtonBinding { diff --git a/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt b/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt index c451118813..b794b23d0e 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt @@ -30,7 +30,6 @@ import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentUserCodeShowBinding import im.vector.app.features.home.AvatarRenderer - import javax.inject.Inject class ShowUserCodeFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index 0771a5d238..5e8145168b 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -24,6 +24,7 @@ import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState @@ -60,8 +61,25 @@ class UserCodeActivity : VectorBaseActivity(), injector.inject(this) } + private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() { + override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { + if (f is MatrixToBottomSheet) { + f.interactionListener = this@UserCodeActivity + } + super.onFragmentResumed(fm, f) + } + + override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { + if (f is MatrixToBottomSheet) { + f.interactionListener = null + } + super.onFragmentPaused(fm, f) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) if (isFirstCreation()) { // should be there early for shared element transition @@ -74,7 +92,7 @@ class UserCodeActivity : VectorBaseActivity(), UserCodeState.Mode.SCAN -> showFragment(ScanUserCodeFragment::class, Bundle.EMPTY) is UserCodeState.Mode.RESULT -> { showFragment(ShowUserCodeFragment::class, Bundle.EMPTY) - MatrixToBottomSheet.withLink(mode.rawLink, this).show(supportFragmentManager, "MatrixToBottomSheet") + MatrixToBottomSheet.withLink(mode.rawLink).show(supportFragmentManager, "MatrixToBottomSheet") } } } @@ -97,6 +115,11 @@ class UserCodeActivity : VectorBaseActivity(), } } + override fun onDestroy() { + supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) + super.onDestroy() + } + private fun showFragment(fragmentClass: KClass, bundle: Bundle) { if (supportFragmentManager.findFragmentByTag(fragmentClass.simpleName) == null) { supportFragmentManager.commitTransaction { @@ -110,10 +133,12 @@ class UserCodeActivity : VectorBaseActivity(), } } - override fun navigateToRoom(roomId: String) { + override fun mxToBottomSheetNavigateToRoom(roomId: String) { navigator.openRoom(this, roomId) } + override fun mxToBottomSheetSwitchToSpace(spaceId: String) {} + override fun onBackPressed() = withState(sharedViewModel) { when (it.mode) { UserCodeState.Mode.SHOW -> super.onBackPressed() diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt index 071044fc8a..74da635787 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt @@ -22,8 +22,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt b/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt index 57f950b2c8..e754eb88f8 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt @@ -16,8 +16,10 @@ package im.vector.app.features.userdirectory +import im.vector.app.features.displayname.getBestName import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.user.model.User +import org.matrix.android.sdk.api.util.toMatrixItem sealed class PendingSelection { data class UserPendingSelection(val user: User) : PendingSelection() @@ -25,7 +27,14 @@ sealed class PendingSelection { fun getBestName(): String { return when (this) { - is UserPendingSelection -> user.getBestName() + is UserPendingSelection -> user.toMatrixItem().getBestName() + is ThreePidPendingSelection -> threePid.value + } + } + + fun getMxId(): String { + return when (this) { + is UserPendingSelection -> user.userId is ThreePidPendingSelection -> threePid.value } } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt index ba740f8556..147367c1da 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt @@ -29,6 +29,7 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider import im.vector.app.core.ui.list.genericPillItem +import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import me.gujun.android.span.span import org.matrix.android.sdk.api.session.Session diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt index f251a672b8..e6d64c799f 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt @@ -43,8 +43,8 @@ import im.vector.app.core.utils.showIdentityServerConsentDialog import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentUserListBinding import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel +import im.vector.app.features.navigation.SettingsActivityPayload import im.vector.app.features.settings.VectorSettingsActivity - import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.user.model.User import javax.inject.Inject @@ -132,9 +132,6 @@ class UserListFragment @Inject constructor( } private fun setupSearchView() { - withState(viewModel) { - views.userListSearch.hint = getString(R.string.user_directory_search_hint_2) - } views.userListSearch .textChanges() .startWith(views.userListSearch.text) @@ -228,9 +225,13 @@ class UserListFragment @Inject constructor( override fun giveIdentityServerConsent() { withState(viewModel) { state -> - requireContext().showIdentityServerConsentDialog(state.configuredIdentityServer) { - viewModel.handle(UserListAction.UpdateUserConsent(true)) - } + requireContext().showIdentityServerConsentDialog( + state.configuredIdentityServer, + policyLinkCallback = { + navigator.openSettings(requireContext(), SettingsActivityPayload.DiscoverySettings(expandIdentityPolicies = true)) + }, + consentCallBack = { viewModel.handle(UserListAction.UpdateUserConsent(true)) } + ) } } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index dead957795..fc0dbbfb73 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -51,8 +51,8 @@ data class ThreePidUser( ) class UserListViewModel @AssistedInject constructor(@Assisted initialState: UserListViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { private val knownUsersSearch = BehaviorRelay.create() private val directoryUsersSearch = BehaviorRelay.create() diff --git a/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt b/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt index b9ad28c2df..a3d4902b41 100644 --- a/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt +++ b/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt @@ -31,8 +31,8 @@ private const val RIOT_BOT_ID = "@riot-bot:matrix.org" */ class ConsentWebViewEventListener(activity: VectorBaseActivity<*>, private val session: Session, - private val delegate: WebViewEventListener) - : WebViewEventListener by delegate { + private val delegate: WebViewEventListener) : + WebViewEventListener by delegate { private val safeActivity: VectorBaseActivity<*>? by weak(activity) diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index 9072957a95..c902b661c0 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -19,10 +19,10 @@ package im.vector.app.features.widgets import android.app.Activity import android.content.Context import android.content.Intent -import com.google.android.material.appbar.MaterialToolbar import androidx.core.view.isVisible import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.viewModel +import com.google.android.material.appbar.MaterialToolbar import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment @@ -33,7 +33,6 @@ import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomShee import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewEvents import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState - import org.matrix.android.sdk.api.session.events.model.Content import java.io.Serializable import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt index 7d2d89e1bd..99b3595d11 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt @@ -18,8 +18,8 @@ package im.vector.app.features.widgets import android.text.TextUtils import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.features.session.coroutineScope diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt index bf27173d83..27a0be83e8 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt @@ -26,8 +26,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.widgets.permissions.WidgetPermissionsHelper @@ -50,8 +50,8 @@ import javax.net.ssl.HttpsURLConnection class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: WidgetViewState, widgetPostAPIHandlerFactory: WidgetPostAPIHandler.Factory, private val stringProvider: StringProvider, - private val session: Session) - : VectorViewModel(initialState), + private val session: Session) : + VectorViewModel(initialState), WidgetPostAPIHandler.NavigationCallback, IntegrationManagerService.Listener { diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt index 4036195b65..68f55773a4 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt @@ -33,7 +33,6 @@ import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetRoomWidgetPermissionBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.widgets.WidgetArgs - import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt index 844a6619b4..e156ad4087 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt @@ -21,8 +21,8 @@ import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch @@ -36,8 +36,8 @@ import timber.log.Timber import java.net.URL class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val initialState: RoomWidgetPermissionViewState, - private val session: Session) - : VectorViewModel(initialState) { + private val session: Session) : + VectorViewModel(initialState) { private val widgetService = session.widgetService() private val integrationManagerService = session.integrationManagerService() 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 6d95911bdb..075d424f0a 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 @@ -25,8 +25,8 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -67,8 +67,8 @@ sealed class BannerState { } class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialState: ServerBackupStatusViewState, - private val session: Session) - : VectorViewModel(initialState), KeysBackupStateListener { + private val session: Session) : + VectorViewModel(initialState), KeysBackupStateListener { @AssistedFactory interface Factory { @@ -116,9 +116,9 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS // So recovery is not setup // Check if cross signing is enabled and local secrets known if ( - crossSigningInfo.getOrNull() == null - || (crossSigningInfo.getOrNull()?.isTrusted() == true - && pInfo.getOrNull()?.allKnown().orFalse()) + crossSigningInfo.getOrNull() == null || + (crossSigningInfo.getOrNull()?.isTrusted() == true && + pInfo.getOrNull()?.allKnown().orFalse()) ) { // So 4S is not setup and we have local secrets, return@Function4 BannerState.Setup(numberOfKeys = getNumberOfKeysToBackup()) diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt index 48459cdd9e..7f089082a2 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -41,7 +41,6 @@ import im.vector.app.databinding.BottomSheetLogoutAndBackupBinding import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet import im.vector.app.features.crypto.recover.SetupMode - import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import javax.inject.Inject diff --git a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml index eae8457121..f42551d39a 100644 --- a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml +++ b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml @@ -172,7 +172,7 @@ android:contentDescription="@string/send" android:scaleType="center" android:src="@drawable/ic_send" - android:visibility="gone" + android:visibility="invisible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" tools:ignore="MissingPrefix" diff --git a/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml b/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml index c09b95f6f7..d6a5b57884 100644 --- a/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml +++ b/vector/src/main/res/layout/composer_layout_constraint_set_expanded.xml @@ -184,7 +184,7 @@ android:contentDescription="@string/send" android:scaleType="center" android:src="@drawable/ic_send" - android:visibility="gone" + android:visibility="invisible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/composer_preview_barrier" diff --git a/vector/src/main/res/layout/fragment_space_add_rooms.xml b/vector/src/main/res/layout/fragment_space_add_rooms.xml index f2150cb390..4a761532e6 100644 --- a/vector/src/main/res/layout/fragment_space_add_rooms.xml +++ b/vector/src/main/res/layout/fragment_space_add_rooms.xml @@ -24,8 +24,7 @@ android:id="@+id/addRoomToSpaceToolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:minHeight="0dp" - app:layout_scrollFlags="scroll|exitUntilCollapsed|snap|enterAlways"> + android:minHeight="0dp"> + + + + + + + + + + diff --git a/vector/src/main/res/layout/item_room_filter_footer.xml b/vector/src/main/res/layout/item_room_filter_footer.xml index 8df6c53032..e727f56f41 100644 --- a/vector/src/main/res/layout/item_room_filter_footer.xml +++ b/vector/src/main/res/layout/item_room_filter_footer.xml @@ -1,5 +1,6 @@ @@ -20,7 +22,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:layout_marginTop="@dimen/layout_vertical_margin" android:text="@string/room_filtering_footer_create_new_room" />