diff --git a/.editorconfig b/.editorconfig index 231d35cfe4..4f23d46afd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -770,7 +770,7 @@ ij_kotlin_align_multiline_extends_list = false ij_kotlin_align_multiline_method_parentheses = false ij_kotlin_align_multiline_parameters = true ij_kotlin_align_multiline_parameters_in_calls = false -ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = false ij_kotlin_assignment_wrap = off ij_kotlin_blank_lines_after_class_header = 0 diff --git a/changelog.d/6200.bugfix b/changelog.d/6200.bugfix new file mode 100644 index 0000000000..ee204b4567 --- /dev/null +++ b/changelog.d/6200.bugfix @@ -0,0 +1 @@ +Fixes room not being in space after upgrade diff --git a/changelog.d/6585.bugfix b/changelog.d/6585.bugfix new file mode 100644 index 0000000000..63bf5a0af6 --- /dev/null +++ b/changelog.d/6585.bugfix @@ -0,0 +1 @@ +Fix backup saving several times the same keys diff --git a/changelog.d/6587.bugfix b/changelog.d/6587.bugfix new file mode 100644 index 0000000000..0273689cfd --- /dev/null +++ b/changelog.d/6587.bugfix @@ -0,0 +1 @@ +Check user power level before sharing live location diff --git a/changelog.d/6596.bugfix b/changelog.d/6596.bugfix new file mode 100644 index 0000000000..8cf97778c8 --- /dev/null +++ b/changelog.d/6596.bugfix @@ -0,0 +1 @@ +[Location Share] - Live is considered as ended while still active diff --git a/fastlane/metadata/android/ar/short_description.txt b/fastlane/metadata/android/ar/short_description.txt index 48df6f2b0c..2b0789b376 100644 --- a/fastlane/metadata/android/ar/short_description.txt +++ b/fastlane/metadata/android/ar/short_description.txt @@ -1 +1 @@ -مُحادثة آمنة لا مركزية و VoIP. حافظ على بياناتك آمنة من الأطراف الثالثة. +برنامج المراسلة الجماعية - الرسائل المشفرة والدردشة الجماعية ومكالمات الفيديو diff --git a/fastlane/metadata/android/ar/title.txt b/fastlane/metadata/android/ar/title.txt index 11992d355d..c2ac1b2876 100644 --- a/fastlane/metadata/android/ar/title.txt +++ b/fastlane/metadata/android/ar/title.txt @@ -1 +1 @@ -‏Element (‏Riot.im سابقًا) +إيليمنت - تطبيق محادثات أمن diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104260.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104260.txt new file mode 100644 index 0000000000..721c24555b --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Podpora UnifiedPush a možnost používat push bez FCM. +Úplný seznam změn: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104270.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104270.txt new file mode 100644 index 0000000000..578549ce6c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability. +Úplný seznam změn: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/et/changelogs/40104260.txt b/fastlane/metadata/android/et/changelogs/40104260.txt new file mode 100644 index 0000000000..2241582817 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: võimalus kasutada tõukesõnumite jaoks FCM'i asemel UnifiedPush'i. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/et/changelogs/40104270.txt b/fastlane/metadata/android/et/changelogs/40104270.txt new file mode 100644 index 0000000000..1df5ac4176 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: erinevate vigade parandused ja stabiilsust edendavad kohendused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fa/changelogs/40104260.txt b/fastlane/metadata/android/fa/changelogs/40104260.txt new file mode 100644 index 0000000000..2e6de40015 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104260.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: استفاده از UnifiedPush و اجازه به کاربر برای داشتن آگاهی‌های ارسالی بدون FCM. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fa/changelogs/40104270.txt b/fastlane/metadata/android/fa/changelogs/40104270.txt new file mode 100644 index 0000000000..29efb95925 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104270.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رفع اشکال‌های مختلف و بهبودهای پایداری. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104260.txt b/fastlane/metadata/android/fr-FR/changelogs/40104260.txt new file mode 100644 index 0000000000..2abff13ba4 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Utilisation de UnifiedPush qui permet aux utilisateur d’utiliser « push » sans FCM. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104270.txt b/fastlane/metadata/android/fr-FR/changelogs/40104270.txt new file mode 100644 index 0000000000..fe61fd021c --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Plusieurs corrections de bogues et d’améliorations de stabilité. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104160.txt b/fastlane/metadata/android/gl/changelogs/40104160.txt new file mode 100644 index 0000000000..ee2cde15ad --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104160.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: melloras na xestión das mensaxes cifradas. Varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104180.txt b/fastlane/metadata/android/gl/changelogs/40104180.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104180.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104190.txt b/fastlane/metadata/android/gl/changelogs/40104190.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104190.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104200.txt b/fastlane/metadata/android/gl/changelogs/40104200.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104200.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104220.txt b/fastlane/metadata/android/gl/changelogs/40104220.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104220.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104230.txt b/fastlane/metadata/android/gl/changelogs/40104230.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104230.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104240.txt b/fastlane/metadata/android/gl/changelogs/40104240.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104240.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104250.txt b/fastlane/metadata/android/gl/changelogs/40104250.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104250.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104260.txt b/fastlane/metadata/android/gl/changelogs/40104260.txt new file mode 100644 index 0000000000..a863d73cc4 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: Utiliza UnifiedPush e permite á usuaria obter notificacións sen FCM. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/changelogs/40104270.txt b/fastlane/metadata/android/gl/changelogs/40104270.txt new file mode 100644 index 0000000000..532464f402 --- /dev/null +++ b/fastlane/metadata/android/gl/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Principais cambios nesta versión: varios arranxos e melloras na estabilidade. +Rexistro completo dos cambios: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/gl/full_description.txt b/fastlane/metadata/android/gl/full_description.txt new file mode 100644 index 0000000000..3502e3ba58 --- /dev/null +++ b/fastlane/metadata/android/gl/full_description.txt @@ -0,0 +1,42 @@ +Element é tanto unha mensaxería segura e unha app de productividade para o traballo en equipo, perfecta para conversas de grupos con traballo remoto. Esta app de chat usa cifrado de extremo-a-extremo para proporcionar video conferencias seguras, compartición de ficheiros e chamadas de voz. + +Características de Element incluídas: +- Ferramentas avanzadas para a comunicación en liña +- Mensaxes completamente cifradas para permitir a comunicación corporativa, incluso para traballo remoto +- Chat descentralizado baseado no sistema de código aberto Matrix +- Compartición segura de ficheiros con datos cifrados na xestión de proxectos +- Chats de vídeo con Voz sobre IP en compartición de pantalla +- Integración doada con outras ferramentas de colaboración en liña, ferramentas de xestión de proxectos, servizos VoIP e outras apps de mensaxería para equipos + +Element é completamente diferente a outras apps de mensaxería e traballo en equipo. Funciona grazas a Matrix, unha rede aberta para mensaxería segura e descentralizada. Permite a hospedaxe na infraestructura propia para proporcionar o maior grao de propiedade e control sobre os teus datos e mensaxes. + +Mensaxería privada e cifrada +Element protéxete da publicidade non solicitada, minería de datos e burbullas de contido. Tamén protexe os teus datos, chamadas de vídeo e voz cifradas de extremo-a-extremo así como verificación con sinatura dos dispositivos. + +Element pon baixo o teu control a túa privacidade permitíndoche comunicarte de xeito seguro con calquera a través da rede Matrix, ou en outras ferramentas de colaboración para empresas ao estar integrada en apps como Slack. + +Element na túa infraestructura +Para un maior control sobre os teus datos sensibles e comunicacións, podes hospedar Element ou elexir calquera hóspede baseado en Matrix - un estándar para comunicación descentralizado e de código aberto. Element proporciona privacidade e seguridade así como flexibilidade para a integración. + +Os teus datos +Ti decides onde gardas os teus datos e mensaxes. Sen o risco da minería de datos ou acceso por terceiras partes. + +Element ponte ao mando de varios xeitos: +1. Consigue unha conta gratuíta no servidor público matrix.org hospedado polos desenvolvedores de Matrix, ou elixe entre miles de servidores públicos xestionados por voluntarias +2. Hospeda a túa conta na túa propia infraestructura IT +3. Crea unha conta nun servidor personalizado simplemente subscribíndote á plataforma de hospedaxe Element Matrix Services + +Mensaxería e Colaboración abertas +Podes conversar con calquera na rede Matrix, tanto se usan Element ou outra app Matrix ou incluso unha mensaxería diferente. + +Super segura +Cifrado real de extremo-a-extremo (só quen participa na conversa pode descifrar as mensaxes), e verificación con sinatura cruzada dos dispositivos. + +Comunicación e integración completas +Mensaxería, chamadas de voz e vídeo, compartición de ficheiros, compartición de pantalla e moitas máis integracións, bots e widgets. Crea salas, comunidades, mantén o contacto e saca adiante o traballo. + +Continúa onde o deixaches +Sigue en contacto alá onde estés grazas ao historial sincronizado de mensaxería entre tódolos dispositivos e na web https://app.element.io + +Código aberto +Element Android é un proxecto de código aberto, hospedado en GitHub. Informa de fallos e/ou contribúe ao seu desenvolvemento en https://github.com/vector-im/element-android diff --git a/fastlane/metadata/android/gl/short_description.txt b/fastlane/metadata/android/gl/short_description.txt new file mode 100644 index 0000000000..7c7f65bf61 --- /dev/null +++ b/fastlane/metadata/android/gl/short_description.txt @@ -0,0 +1 @@ +Mensaxería en grupo - mensaxería cifrada, chat en grupo e videochamadas diff --git a/fastlane/metadata/android/gl/title.txt b/fastlane/metadata/android/gl/title.txt new file mode 100644 index 0000000000..0fb73bc324 --- /dev/null +++ b/fastlane/metadata/android/gl/title.txt @@ -0,0 +1 @@ +Element - Mensaxería Segura diff --git a/fastlane/metadata/android/id/changelogs/40104260.txt b/fastlane/metadata/android/id/changelogs/40104260.txt new file mode 100644 index 0000000000..bfd9637fda --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Dukungan UnifiedPush, memungkinkan pengguna untuk diberitahukan tanpa FCM. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/id/changelogs/40104270.txt b/fastlane/metadata/android/id/changelogs/40104270.txt new file mode 100644 index 0000000000..1017951d47 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Banyak perbaikan kutu dan perbaikan stabilitas. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/it-IT/changelogs/40104260.txt b/fastlane/metadata/android/it-IT/changelogs/40104260.txt new file mode 100644 index 0000000000..d52ed6b769 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: utilizza UnifiedPush e consente all'utente di avere notifiche push senza FCM. +Cronologia completa: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/it-IT/changelogs/40104270.txt b/fastlane/metadata/android/it-IT/changelogs/40104270.txt new file mode 100644 index 0000000000..556a6fc7ea --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: varie correzioni di errori e miglioramenti della stabilità. +Cronologia completa: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sk/changelogs/40104260.txt b/fastlane/metadata/android/sk/changelogs/40104260.txt new file mode 100644 index 0000000000..6980671174 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Použitie UnifiedPush a umožňuje používateľovi používať push bez FCM. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sk/changelogs/40104270.txt b/fastlane/metadata/android/sk/changelogs/40104270.txt new file mode 100644 index 0000000000..50670f18c2 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Rôzne opravy chýb a vylepšenia stability. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104260.txt b/fastlane/metadata/android/sv-SE/changelogs/40104260.txt new file mode 100644 index 0000000000..99185d8562 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Använd UnifiedPush och tillåt användare att ha push utan FCM. +Full ändringslogg: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104270.txt b/fastlane/metadata/android/sv-SE/changelogs/40104270.txt new file mode 100644 index 0000000000..d8db452b51 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Diverse buggfixar och stabilitetsförbättringar. +Full ändringslogg: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/uk/changelogs/40101000.txt b/fastlane/metadata/android/uk/changelogs/40101000.txt index 36870f5ef7..1b7d25f1b9 100644 --- a/fastlane/metadata/android/uk/changelogs/40101000.txt +++ b/fastlane/metadata/android/uk/changelogs/40101000.txt @@ -1,2 +1,2 @@ -Основні зміни в цій версії: поліпшення VoIP (аудіо та відео дзвінки в DM) та виправлення помилок! +Основні зміни в цій версії: поліпшення VoIP (аудіо та відеовиклики у ПП) та виправлення помилок! Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.0 diff --git a/fastlane/metadata/android/uk/changelogs/40104260.txt b/fastlane/metadata/android/uk/changelogs/40104260.txt new file mode 100644 index 0000000000..3e3219946a --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104260.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Застосовано UnifiedPush і дозволено користувачам отримувати push-сповіщення без FCM. +Перелік усіх змін: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/uk/changelogs/40104270.txt b/fastlane/metadata/android/uk/changelogs/40104270.txt new file mode 100644 index 0000000000..9664c615c1 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104270.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Усунуто різні вади й поліпшено стабільність. +Перелік усіх змін: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104260.txt b/fastlane/metadata/android/zh-TW/changelogs/40104260.txt new file mode 100644 index 0000000000..7569b4f491 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104260.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:使用 UnifiedPush 並允許使用者在沒有 FCM 的情況下推送。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104270.txt b/fastlane/metadata/android/zh-TW/changelogs/40104270.txt new file mode 100644 index 0000000000..4bcca9a0b8 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104270.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:多個臭蟲修復與穩定性改善。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 6f1646ec53..ee58db748c 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -199,7 +199,7 @@ dependencies { implementation libs.apache.commonsImaging // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.51' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.52' testImplementation libs.tests.junit // Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281 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 e160938721..2439119f01 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -24,7 +24,6 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.FixMethodOrder -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -56,7 +55,6 @@ import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @LargeTest -@Ignore class KeysBackupTest : InstrumentedTest { @get:Rule val rule = RetryTestRule(3) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/VersioningState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/VersioningState.kt index 2e1668ebbb..8cfe3da031 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/VersioningState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/VersioningState.kt @@ -33,5 +33,7 @@ enum class VersioningState { /** * The room has been upgraded, and the new room has been joined. */ - UPGRADED_ROOM_JOINED, + UPGRADED_ROOM_JOINED; + + fun isUpgraded() = this != NONE } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt index 56425cbc74..46ebbb7b71 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt @@ -37,9 +37,9 @@ import org.matrix.android.sdk.internal.auth.db.PendingSessionData * This class execute the registration request and is responsible to keep the session of interactive authentication. */ internal class DefaultRegistrationWizard( - authAPI: AuthAPI, - private val sessionCreator: SessionCreator, - private val pendingSessionStore: PendingSessionStore + authAPI: AuthAPI, + private val sessionCreator: SessionCreator, + private val pendingSessionStore: PendingSessionStore ) : RegistrationWizard { private var pendingSessionData: PendingSessionData = pendingSessionStore.getPendingSessionData() ?: error("Pending session data should exist here") @@ -74,20 +74,20 @@ internal class DefaultRegistrationWizard( initialDeviceDisplayName: String? ): RegistrationResult { val params = RegistrationParams( - username = userName, - password = password, - initialDeviceDisplayName = initialDeviceDisplayName + username = userName, + password = password, + initialDeviceDisplayName = initialDeviceDisplayName ) return performRegistrationRequest(params, LoginType.PASSWORD) - .also { - pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true) - .also { pendingSessionStore.savePendingSessionData(it) } - } + .also { + pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true) + .also { pendingSessionStore.savePendingSessionData(it) } + } } override suspend fun performReCaptcha(response: String): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams.createForCaptcha(safeSession, response)) return performRegistrationRequest(params, LoginType.PASSWORD) @@ -95,7 +95,7 @@ internal class DefaultRegistrationWizard( override suspend fun acceptTerms(): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.TERMS, session = safeSession)) return performRegistrationRequest(params, LoginType.PASSWORD) @@ -103,14 +103,14 @@ internal class DefaultRegistrationWizard( override suspend fun addThreePid(threePid: RegisterThreePid): RegistrationResult { pendingSessionData = pendingSessionData.copy(currentThreePidData = null) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } return sendThreePid(threePid) } override suspend fun sendAgainThreePid(): RegistrationResult { val safeCurrentThreePid = pendingSessionData.currentThreePidData?.threePid - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") return sendThreePid(safeCurrentThreePid) } @@ -126,7 +126,7 @@ internal class DefaultRegistrationWizard( ) pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } val params = RegistrationParams( auth = if (threePid is RegisterThreePid.Email) { @@ -149,7 +149,7 @@ internal class DefaultRegistrationWizard( ) // Store data pendingSessionData = pendingSessionData.copy(currentThreePidData = ThreePidData.from(threePid, response, params)) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } // and send the sid a first time return performRegistrationRequest(params, LoginType.PASSWORD) @@ -157,7 +157,7 @@ internal class DefaultRegistrationWizard( override suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult { val safeParam = pendingSessionData.currentThreePidData?.registrationParams - ?: throw IllegalStateException("developer error, no pending three pid") + ?: throw IllegalStateException("developer error, no pending three pid") return performRegistrationRequest(safeParam, LoginType.PASSWORD, delayMillis) } @@ -168,13 +168,13 @@ internal class DefaultRegistrationWizard( private suspend fun validateThreePid(code: String): RegistrationResult { val registrationParams = pendingSessionData.currentThreePidData?.registrationParams - ?: throw IllegalStateException("developer error, no pending three pid") + ?: throw IllegalStateException("developer error, no pending three pid") val safeCurrentData = pendingSessionData.currentThreePidData ?: throw IllegalStateException("developer error, call createAccount() method first") val url = safeCurrentData.addThreePidRegistrationResponse.submitUrl ?: throw IllegalStateException("Missing url to send the code") val validationBody = ValidationCodeBody( - clientSecret = pendingSessionData.clientSecret, - sid = safeCurrentData.addThreePidRegistrationResponse.sid, - code = code + clientSecret = pendingSessionData.clientSecret, + sid = safeCurrentData.addThreePidRegistrationResponse.sid, + code = code ) val validationResponse = validateCodeTask.execute(ValidateCodeTask.Params(url, validationBody)) if (validationResponse.isSuccess()) { @@ -189,7 +189,7 @@ internal class DefaultRegistrationWizard( override suspend fun dummy(): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.DUMMY, session = safeSession)) return performRegistrationRequest(params, LoginType.PASSWORD) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt index ab7cbb74b1..39dfb72149 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt @@ -21,13 +21,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import timber.log.Timber -import java.util.Timer -import java.util.TimerTask import javax.inject.Inject internal data class InboundGroupSessionHolder( @@ -57,18 +54,13 @@ internal class InboundGroupSessionStore @Inject constructor( if (oldValue != null) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { Timber.tag(loggerTag.value).v("## Inbound: entryRemoved ${oldValue.wrapper.roomId}-${oldValue.wrapper.senderKey}") - store.storeInboundGroupSessions(listOf(oldValue).map { it.wrapper }) + // store.storeInboundGroupSessions(listOf(oldValue).map { it.wrapper }) oldValue.wrapper.session.releaseSession() } } } } - private val timer = Timer() - private var timerTask: TimerTask? = null - - private val dirtySession = mutableListOf() - @Synchronized fun clear() { sessionCache.evictAll() @@ -90,7 +82,6 @@ internal class InboundGroupSessionStore @Inject constructor( @Synchronized fun replaceGroupSession(old: InboundGroupSessionHolder, new: InboundGroupSessionHolder, sessionId: String, senderKey: String) { Timber.tag(loggerTag.value).v("## Replacing outdated session ${old.wrapper.roomId}-${old.wrapper.senderKey}") - dirtySession.remove(old) store.removeInboundGroupSession(sessionId, senderKey) sessionCache.remove(CacheKey(sessionId, senderKey)) @@ -107,33 +98,14 @@ internal class InboundGroupSessionStore @Inject constructor( private fun internalStoreGroupSession(holder: InboundGroupSessionHolder, sessionId: String, senderKey: String) { Timber.tag(loggerTag.value).v("## Inbound: getInboundGroupSession mark as dirty ${holder.wrapper.roomId}-${holder.wrapper.senderKey}") - // We want to batch this a bit for performances - dirtySession.add(holder) if (sessionCache[CacheKey(sessionId, senderKey)] == null) { // first time seen, put it in memory cache while waiting for batch insert // If it's already known, no need to update cache it's already there sessionCache.put(CacheKey(sessionId, senderKey), holder) } - - timerTask?.cancel() - timerTask = object : TimerTask() { - override fun run() { - batchSave() - } - } - timer.schedule(timerTask!!, 300) - } - - @Synchronized - private fun batchSave() { - val toSave = mutableListOf().apply { addAll(dirtySession) } - dirtySession.clear() cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - Timber.tag(loggerTag.value).v("## Inbound: getInboundGroupSession batching save of ${toSave.size}") - tryOrNull { - store.storeInboundGroupSessions(toSave.map { it.wrapper }) - } + store.storeInboundGroupSessions(listOf(holder.wrapper)) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index c4a6488258..96ccba51dc 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -604,14 +604,16 @@ internal class MXOlmDevice @Inject constructor( * @param sharedHistory MSC3061, this key is sharable on invite * @return true if the operation succeeds. */ - fun addInboundGroupSession(sessionId: String, - sessionKey: String, - roomId: String, - senderKey: String, - forwardingCurve25519KeyChain: List, - keysClaimed: Map, - exportFormat: Boolean, - sharedHistory: Boolean): AddSessionResult { + fun addInboundGroupSession( + sessionId: String, + sessionKey: String, + roomId: String, + senderKey: String, + forwardingCurve25519KeyChain: List, + keysClaimed: Map, + exportFormat: Boolean, + sharedHistory: Boolean + ): AddSessionResult { val candidateSession = tryOrNull("Failed to create inbound session in room $roomId") { if (exportFormat) { OlmInboundGroupSession.importSession(sessionKey) @@ -701,8 +703,8 @@ internal class MXOlmDevice @Inject constructor( val senderKey = megolmSessionData.senderKey ?: continue val roomId = megolmSessionData.roomId - val candidateSessionToImport = try { - MXInboundMegolmSessionWrapper.newFromMegolmData(megolmSessionData, true) + val candidateSessionToImport = try { + MXInboundMegolmSessionWrapper.newFromMegolmData(megolmSessionData, true) } catch (e: Throwable) { Timber.tag(loggerTag.value).e(e, "## importInboundGroupSession() : Failed to import session $senderKey/$sessionId") continue @@ -806,7 +808,6 @@ internal class MXOlmDevice @Inject constructor( } replayAttackMap[messageIndexKey] = eventId } - inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) val payload = try { val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) 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 414416a0f6..38edbb7430 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 @@ -38,6 +38,7 @@ internal class MXMegolmDecryptionFactory @Inject constructor( outgoingKeyRequestManager, cryptoStore, matrixConfiguration, - eventsManager) + eventsManager + ) } } 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 48a25f2a8b..ceaee582c7 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 @@ -250,8 +250,10 @@ internal class MXMegolmEncryption( * @param sessionInfo the session info * @param devicesByUser the devices map */ - private suspend fun shareUserDevicesKey(sessionInfo: MXOutboundSessionInfo, - devicesByUser: Map>) { + private suspend fun shareUserDevicesKey( + sessionInfo: MXOutboundSessionInfo, + devicesByUser: Map> + ) { val sessionKey = olmDevice.getSessionKey(sessionInfo.sessionId) ?: return Unit.also { Timber.tag(loggerTag.value).v("shareUserDevicesKey() Failed to share session, failed to export") } 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 49cf60d051..8691c08779 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 @@ -1349,6 +1349,8 @@ internal class DefaultKeysBackupService @Inject constructor( // Mark keys as backed up cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers) + // we can release the sessions now + olmInboundGroupSessionWrappers.onEach { it.session.releaseSession() } if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) { Timber.v("backupKeys: All keys have been backed up") 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 20ca357d1a..f5468634cb 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 @@ -763,11 +763,17 @@ internal class RealmCryptoStore @Inject constructor( // } ?: false val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, wrapper.sessionData.senderKey) + val existing = realm.where() + .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) + .findFirst() + val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply { primaryKey = key store(wrapper) + backedUp = existing?.backedUp ?: false } - Timber.i("## CRYPTO | shouldShareHistory: ${wrapper.sessionData.sharedHistory} for $key") + + Timber.v("## CRYPTO | shouldShareHistory: ${wrapper.sessionData.sharedHistory} for $key") realm.insertOrUpdate(realmOlmInboundGroupSession) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo034.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo034.kt index f7c50477e5..b23e84706f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo034.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo034.kt @@ -17,14 +17,18 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator +/** + * Migrating to: + * Live location sharing aggregated summary: adding new field startOfLiveTimestampMillis. + */ internal class MigrateSessionTo034(realm: DynamicRealm) : RealmMigrator(realm, 34) { override fun doMigrate(realm: DynamicRealm) { - realm.schema.get("RoomSummaryEntity") - ?.addRealmListField(RoomSummaryEntityFields.DIRECT_PARENT_NAMES.`$`, String::class.java) - ?.transform { it.setString(RoomSummaryEntityFields.DIRECT_PARENT_NAMES.`$`, "") } + realm.schema.get("LiveLocationShareAggregatedSummaryEntity") + ?.addField(LiveLocationShareAggregatedSummaryEntityFields.START_OF_LIVE_TIMESTAMP_MILLIS, Long::class.java) + ?.setNullable(LiveLocationShareAggregatedSummaryEntityFields.START_OF_LIVE_TIMESTAMP_MILLIS, true) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt index 08ea06bb1e..ca793ffd8e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/livelocation/LiveLocationShareAggregatedSummaryEntity.kt @@ -44,6 +44,8 @@ internal open class LiveLocationShareAggregatedSummaryEntity( */ var isActive: Boolean? = null, + var startOfLiveTimestampMillis: Long? = null, + var endOfLiveTimestampMillis: Long? = null, /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt index fbf7e963a7..a1179ccdce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt @@ -92,12 +92,14 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveIn roomId: String, userId: String, ignoredEventId: String, + startOfLiveTimestampThreshold: Long, ): List { return LiveLocationShareAggregatedSummaryEntity .whereRoomId(realm, roomId = roomId) .equalTo(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, userId) .equalTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true) .notEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, ignoredEventId) + .lessThan(LiveLocationShareAggregatedSummaryEntityFields.START_OF_LIVE_TIMESTAMP_MILLIS, startOfLiveTimestampThreshold) .findAll() .toList() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt index 3f5b1e1360..510c20497b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -84,11 +84,12 @@ internal class LiveLocationAggregationProcessor @Inject constructor( val endOfLiveTimestampMillis = content.getBestTimestampMillis()?.let { it + (content.timeout ?: 0) } Timber.d("updating summary of id=$targetEventId with isActive=$isActive and endTimestamp=$endOfLiveTimestampMillis") + aggregatedSummary.startOfLiveTimestampMillis = content.getBestTimestampMillis() aggregatedSummary.endOfLiveTimestampMillis = endOfLiveTimestampMillis aggregatedSummary.isActive = isActive aggregatedSummary.userId = event.senderId - deactivateAllPreviousBeacons(realm, roomId, event.senderId, targetEventId) + deactivateAllPreviousBeacons(realm, roomId, event.senderId, targetEventId, content.getBestTimestampMillis() ?: 0) if (isActive) { scheduleDeactivationAfterTimeout(targetEventId, roomId, endOfLiveTimestampMillis) @@ -182,13 +183,20 @@ internal class LiveLocationAggregationProcessor @Inject constructor( aggregatedSummary.relatedEventIds = RealmList(*updatedEventIds.toTypedArray()) } - private fun deactivateAllPreviousBeacons(realm: Realm, roomId: String, userId: String, currentEventId: String) { + private fun deactivateAllPreviousBeacons( + realm: Realm, + roomId: String, + userId: String, + currentEventId: String, + currentEventTimestamp: Long + ) { LiveLocationShareAggregatedSummaryEntity .findActiveLiveInRoomForUser( realm = realm, roomId = roomId, userId = userId, - ignoredEventId = currentEventId + ignoredEventId = currentEventId, + startOfLiveTimestampThreshold = currentEventTimestamp ) .forEach { it.isActive = false } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/fatal.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/fatal.kt index 323eee0b1c..7ed807d7cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/fatal.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/fatal.kt @@ -22,7 +22,7 @@ import timber.log.Timber /** * Throws in debug, only log in production. * As this method does not always throw, next statement should be a return. -*/ + */ internal fun fatalError(message: String) { if (BuildConfig.DEBUG) { error(message) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt index a5e91714b7..25d441ef5c 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.test.fakes.FakeWorkManagerProvider import org.matrix.android.sdk.test.fakes.givenEqualTo import org.matrix.android.sdk.test.fakes.givenFindAll import org.matrix.android.sdk.test.fakes.givenFindFirst +import org.matrix.android.sdk.test.fakes.givenLessThan import org.matrix.android.sdk.test.fakes.givenNotEqualTo private const val A_SESSION_ID = "session_id" @@ -183,6 +184,7 @@ internal class LiveLocationAggregationProcessorTest { aggregatedEntity.roomId shouldBeEqualTo A_ROOM_ID aggregatedEntity.userId shouldBeEqualTo A_SENDER_ID aggregatedEntity.isActive shouldBeEqualTo true + aggregatedEntity.startOfLiveTimestampMillis shouldBeEqualTo A_TIMESTAMP aggregatedEntity.endOfLiveTimestampMillis shouldBeEqualTo A_TIMESTAMP + A_TIMEOUT_MILLIS aggregatedEntity.lastLocationContent shouldBeEqualTo null previousEntities.forEach { entity -> @@ -404,6 +406,7 @@ internal class LiveLocationAggregationProcessorTest { .givenNotEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, AN_EVENT_ID) .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, A_SENDER_ID) .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true) + .givenLessThan(LiveLocationShareAggregatedSummaryEntityFields.START_OF_LIVE_TIMESTAMP_MILLIS, A_TIMESTAMP) .givenFindAll(summaryList) return summaryList } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt index cb40889fb7..afdcf111f8 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt @@ -101,6 +101,14 @@ inline fun RealmQuery.givenIsNotNull( return this } +inline fun RealmQuery.givenLessThan( + fieldName: String, + value: Long +): RealmQuery { + every { lessThan(fieldName, value) } returns this + return this +} + /** * Should be called on a mocked RealmObject and not on a real RealmObject so that the underlying final method is mocked. */ diff --git a/vector/build.gradle b/vector/build.gradle index aba53bf89c..e4313770c4 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -437,7 +437,7 @@ dependencies { implementation 'com.facebook.stetho:stetho:1.6.0' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.51' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.52' // FlowBinding implementation libs.github.flowBinding diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt index e63aafbfc4..d71e52de8c 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt @@ -21,11 +21,11 @@ import im.vector.app.features.onboarding.AuthenticationDescription fun AuthenticationDescription.AuthenticationType.toAnalyticsType() = when (this) { AuthenticationDescription.AuthenticationType.Password -> Signup.AuthenticationType.Password - AuthenticationDescription.AuthenticationType.Apple -> Signup.AuthenticationType.Apple + AuthenticationDescription.AuthenticationType.Apple -> Signup.AuthenticationType.Apple AuthenticationDescription.AuthenticationType.Facebook -> Signup.AuthenticationType.Facebook AuthenticationDescription.AuthenticationType.GitHub -> Signup.AuthenticationType.GitHub AuthenticationDescription.AuthenticationType.GitLab -> Signup.AuthenticationType.GitLab AuthenticationDescription.AuthenticationType.Google -> Signup.AuthenticationType.Google - AuthenticationDescription.AuthenticationType.SSO -> Signup.AuthenticationType.SSO - AuthenticationDescription.AuthenticationType.Other -> Signup.AuthenticationType.Other + AuthenticationDescription.AuthenticationType.SSO -> Signup.AuthenticationType.SSO + AuthenticationDescription.AuthenticationType.Other -> Signup.AuthenticationType.Other } diff --git a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt index 4b32f3307f..f4ffbb826a 100644 --- a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt @@ -70,7 +70,7 @@ class AvatarRenderer @Inject constructor( render( GlideApp.with(imageView), matrixItem, - DrawableImageViewTarget(imageView) + DrawableImageViewTarget(imageView), ) } @@ -103,7 +103,7 @@ class AvatarRenderer @Inject constructor( render( glideRequests, matrixItem, - DrawableImageViewTarget(imageView) + DrawableImageViewTarget(imageView), ) } @@ -123,7 +123,7 @@ class AvatarRenderer @Inject constructor( val matrixItem = MatrixItem.UserItem( // Need an id starting with @ id = "@${mappedContact.displayName}", - displayName = mappedContact.displayName + displayName = mappedContact.displayName, ) val placeholder = getPlaceholderDrawable(matrixItem) @@ -140,7 +140,7 @@ class AvatarRenderer @Inject constructor( val matrixItem = MatrixItem.UserItem( // Need an id starting with @ id = profileInfo.matrixId, - displayName = profileInfo.displayName + displayName = profileInfo.displayName, ) val placeholder = getPlaceholderDrawable(matrixItem) @@ -215,7 +215,7 @@ class AvatarRenderer @Inject constructor( .bold() .endConfig() .buildRect(matrixItem.firstLetterOfDisplayName(), avatarColor) - .toBitmap(width = iconSize, height = iconSize) + .toBitmap(width = iconSize, height = iconSize), ) } } @@ -231,7 +231,7 @@ class AvatarRenderer @Inject constructor( addPlaceholder: Boolean ) { val transformations = mutableListOf>( - BlurTransformation(20, sampling) + BlurTransformation(20, sampling), ) if (colorFilter != null) { transformations.add(ColorFilterTransformation(colorFilter)) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index d82621977f..926c1eb113 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -219,7 +219,7 @@ class HomeActivity : is HomeActivitySharedAction.ShowSpaceSettings -> showSpaceSettings(sharedAction.spaceId) is HomeActivitySharedAction.OpenSpaceInvite -> openSpaceInvite(sharedAction.spaceId) HomeActivitySharedAction.SendSpaceFeedBack -> bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK) - HomeActivitySharedAction.OnCloseSpace -> onCloseSpace() + HomeActivitySharedAction.OnCloseSpace -> onCloseSpace() } } .launchIn(lifecycleScope) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt index 5f32696334..69b4f6e039 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt @@ -63,10 +63,10 @@ class EncryptionItemFactory @Inject constructor( isDirect && RoomLocalEcho.isLocalEchoId(event.root.roomId.orEmpty()) -> { R.string.direct_room_encryption_enabled_tile_description_future } - isDirect -> { + isDirect -> { R.string.direct_room_encryption_enabled_tile_description } - else -> { + else -> { R.string.encryption_enabled_tile_description } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/UpgradeRoomViewModelTask.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/UpgradeRoomViewModelTask.kt index 2f91b9a35a..1f0404d659 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/UpgradeRoomViewModelTask.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/UpgradeRoomViewModelTask.kt @@ -84,8 +84,6 @@ class UpgradeRoomViewModelTask @Inject constructor( // autoJoin = currentInfo.autoJoin ?: false, suggested = currentInfo.suggested ) - - parentSpace.removeChildren(params.roomId) } } } catch (failure: Throwable) { 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 44d61f9ed2..77f7c148d9 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 @@ -146,17 +146,17 @@ class RoomListViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val roomListSectionBuilder = RoomListSectionBuilder( - session, - stringProvider, - appStateHandler, - viewModelScope, - autoAcceptInvites, - { - updatableQuery = it - }, - suggestedRoomJoiningState, - !vectorPreferences.prefSpacesShowAllRoomInHome() - ) + session, + stringProvider, + appStateHandler, + viewModelScope, + autoAcceptInvites, + { + updatableQuery = it + }, + suggestedRoomJoiningState, + !vectorPreferences.prefSpacesShowAllRoomInHome() + ) val sections: List by lazy { roomListSectionBuilder.buildSections(initialState.displayMode) diff --git a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt index 412b28862a..725f23cddd 100644 --- a/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/html/EventHtmlRenderer.kt @@ -85,27 +85,27 @@ class EventHtmlRenderer @Inject constructor( } else { builder } - .usePlugin( - MarkwonInlineParserPlugin.create( - /* Configuring the Markwon inline formatting processor. - * Default settings are all Markdown features. Turn those off, only using the - * inline HTML processor and HTML entities processor. - */ - MarkwonInlineParser.factoryBuilderNoDefaults() - .addInlineProcessor(HtmlInlineProcessor()) // use inline HTML processor - .addInlineProcessor(EntityInlineProcessor()) // use HTML entities processor + .usePlugin( + MarkwonInlineParserPlugin.create( + /* Configuring the Markwon inline formatting processor. + * Default settings are all Markdown features. Turn those off, only using the + * inline HTML processor and HTML entities processor. + */ + MarkwonInlineParser.factoryBuilderNoDefaults() + .addInlineProcessor(HtmlInlineProcessor()) // use inline HTML processor + .addInlineProcessor(EntityInlineProcessor()) // use HTML entities processor + ) ) - ) - .usePlugin(object : AbstractMarkwonPlugin() { - override fun configureParser(builder: Parser.Builder) { - /* Configuring the Markwon block formatting processor. - * Default settings are all Markdown blocks. Turn those off. - */ - builder.enabledBlockTypes(kotlin.collections.emptySet()) - } - }) - .textSetter(PrecomputedFutureTextSetterCompat.create()) - .build() + .usePlugin(object : AbstractMarkwonPlugin() { + override fun configureParser(builder: Parser.Builder) { + /* Configuring the Markwon block formatting processor. + * Default settings are all Markdown blocks. Turn those off. + */ + builder.enabledBlockTypes(kotlin.collections.emptySet()) + } + }) + .textSetter(PrecomputedFutureTextSetterCompat.create()) + .build() val plugins: List = markwon.plugins diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt index d86d97e6b0..264b1f0e0b 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt @@ -23,5 +23,6 @@ sealed class LocationSharingAction : VectorViewModelAction { data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction() data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction() object ZoomToUserLocation : LocationSharingAction() + object LiveLocationSharingRequested : LocationSharingAction() data class StartLiveLocationSharing(val durationMillis: Long) : LocationSharingAction() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index be5f0aed6f..17e53e63d1 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -104,6 +104,9 @@ class LocationSharingFragment @Inject constructor( LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError() is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it) is LocationSharingViewEvents.StartLiveLocationService -> handleStartLiveLocationService(it) + LocationSharingViewEvents.ChooseLiveLocationDuration -> handleChooseLiveLocationDuration() + LocationSharingViewEvents.ShowLabsFlagPromotion -> handleShowLabsFlagPromotion() + LocationSharingViewEvents.LiveLocationSharingNotEnoughPermission -> handleLiveLocationSharingNotEnoughPermission() } } } @@ -168,6 +171,14 @@ class LocationSharingFragment @Inject constructor( .show() } + private fun handleLiveLocationSharingNotEnoughPermission() { + MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.live_location_not_enough_permission_dialog_title) + .setMessage(R.string.live_location_not_enough_permission_dialog_description) + .setPositiveButton(R.string.ok, null) + .show() + } + private fun initLocateButton() { views.mapView.locateButton.setOnClickListener { viewModel.handle(LocationSharingAction.ZoomToUserLocation) @@ -201,7 +212,7 @@ class LocationSharingFragment @Inject constructor( viewModel.handle(LocationSharingAction.CurrentUserLocationSharing) } views.shareLocationOptionsPicker.optionUserLive.debouncedClicks { - tryStartLiveLocationSharing() + viewModel.handle(LocationSharingAction.LiveLocationSharingRequested) } } @@ -212,13 +223,13 @@ class LocationSharingFragment @Inject constructor( } } - private fun tryStartLiveLocationSharing() { - if (vectorPreferences.labsEnableLiveLocation()) { - startLiveLocationSharing() - } else { - LiveLocationLabsFlagPromotionBottomSheet.newInstance() - .show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION") - } + private fun handleChooseLiveLocationDuration() { + startLiveLocationSharing() + } + + private fun handleShowLabsFlagPromotion() { + LiveLocationLabsFlagPromotionBottomSheet.newInstance() + .show(requireActivity().supportFragmentManager, "DISPLAY_LIVE_LOCATION_LABS_FLAG_PROMOTION") } private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt index 1116003e41..c9e411c8d7 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt @@ -23,4 +23,7 @@ sealed class LocationSharingViewEvents : VectorViewEvents { object LocationNotAvailableError : LocationSharingViewEvents() data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents() data class StartLiveLocationService(val sessionId: String, val roomId: String, val durationMillis: Long) : LocationSharingViewEvents() + object ChooseLiveLocationDuration : LocationSharingViewEvents() + object ShowLabsFlagPromotion : LocationSharingViewEvents() + object LiveLocationSharingNotEnoughPermission : LocationSharingViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt index b9a2dc830c..8056b72d57 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt @@ -26,6 +26,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider import im.vector.app.features.location.domain.usecase.CompareLocationsUseCase +import im.vector.app.features.powerlevel.PowerLevelsFlowFactory +import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.lastOrNull @@ -36,8 +38,10 @@ import kotlinx.coroutines.flow.sample import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse 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.getRoom import org.matrix.android.sdk.api.session.getUser +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.util.toMatrixItem import timber.log.Timber @@ -52,6 +56,7 @@ class LocationSharingViewModel @AssistedInject constructor( private val locationPinProvider: LocationPinProvider, private val session: Session, private val compareLocationsUseCase: CompareLocationsUseCase, + private val vectorPreferences: VectorPreferences, ) : VectorViewModel(initialState), LocationTracker.Callback { private val room = session.getRoom(initialState.roomId)!! @@ -70,6 +75,21 @@ class LocationSharingViewModel @AssistedInject constructor( setUserItem() updatePin() compareTargetAndUserLocation() + observePowerLevelsForLiveLocationSharing() + } + + private fun observePowerLevelsForLiveLocationSharing() { + PowerLevelsFlowFactory(room).createFlow() + .distinctUntilChanged() + .setOnEach { + val powerLevelsHelper = PowerLevelsHelper(it) + val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO + .all { beaconInfoType -> + powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType) + } + + copy(canShareLiveLocation = canShareLiveLocation) + } } private fun initLocationTracking() { @@ -130,10 +150,21 @@ class LocationSharingViewModel @AssistedInject constructor( is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action) is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action) LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction() + LocationSharingAction.LiveLocationSharingRequested -> handleLiveLocationSharingRequestedAction() is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.durationMillis) } } + private fun handleLiveLocationSharingRequestedAction() = withState { state -> + if (!state.canShareLiveLocation) { + _viewEvents.post(LocationSharingViewEvents.LiveLocationSharingNotEnoughPermission) + } else if (vectorPreferences.labsEnableLiveLocation()) { + _viewEvents.post(LocationSharingViewEvents.ChooseLiveLocationDuration) + } else { + _viewEvents.post(LocationSharingViewEvents.ShowLabsFlagPromotion) + } + } + private fun handleCurrentUserLocationSharingAction() = withState { state -> shareLocation(state.lastKnownUserLocation, isUserLocation = true) } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewState.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewState.kt index 64f324bc1b..d5226eacfb 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewState.kt @@ -34,7 +34,8 @@ data class LocationSharingViewState( val userItem: MatrixItem.UserItem? = null, val areTargetAndUserLocationEqual: Boolean? = null, val lastKnownUserLocation: LocationData? = null, - val locationTargetDrawable: Drawable? = null + val locationTargetDrawable: Drawable? = null, + val canShareLiveLocation: Boolean = false, ) : MavericksState { constructor(locationSharingArgs: LocationSharingArgs) : this( diff --git a/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt b/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt index cf360ec277..be8e774ad0 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/LiveLocationLabsFlagPromotionBottomSheet.kt @@ -29,7 +29,7 @@ import im.vector.app.databinding.BottomSheetLiveLocationLabsFlagPromotionBinding * This should not be shown if the user already enabled the labs flag. */ class LiveLocationLabsFlagPromotionBottomSheet : - VectorBaseBottomSheetDialogFragment() { + VectorBaseBottomSheetDialogFragment() { override val showExpanded = true diff --git a/vector/src/main/java/im/vector/app/features/onboarding/AuthenticationDescription.kt b/vector/src/main/java/im/vector/app/features/onboarding/AuthenticationDescription.kt index 3672b8eef3..c540871ab7 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/AuthenticationDescription.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/AuthenticationDescription.kt @@ -41,12 +41,12 @@ sealed interface AuthenticationDescription : Parcelable { } fun SsoIdentityProvider?.toAuthenticationType() = when (this?.brand) { - SsoIdentityProvider.BRAND_GOOGLE -> AuthenticationType.Google - SsoIdentityProvider.BRAND_GITHUB -> AuthenticationType.GitHub - SsoIdentityProvider.BRAND_APPLE -> AuthenticationType.Apple + SsoIdentityProvider.BRAND_GOOGLE -> AuthenticationType.Google + SsoIdentityProvider.BRAND_GITHUB -> AuthenticationType.GitHub + SsoIdentityProvider.BRAND_APPLE -> AuthenticationType.Apple SsoIdentityProvider.BRAND_FACEBOOK -> AuthenticationType.Facebook - SsoIdentityProvider.BRAND_GITLAB -> AuthenticationType.GitLab - SsoIdentityProvider.BRAND_TWITTER -> AuthenticationType.SSO - null -> AuthenticationType.SSO - else -> AuthenticationType.SSO + SsoIdentityProvider.BRAND_GITLAB -> AuthenticationType.GitLab + SsoIdentityProvider.BRAND_TWITTER -> AuthenticationType.SSO + null -> AuthenticationType.SSO + else -> AuthenticationType.SSO } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index add4bd3ab6..52c32d88e4 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -563,7 +563,7 @@ class OnboardingViewModel @AssistedInject constructor( setState { copy(isLoading = false, resetState = ResetState()) } val nextEvent = when { vectorFeatures.isOnboardingCombinedLoginEnabled() -> OnboardingViewEvents.OnResetPasswordComplete - else -> OnboardingViewEvents.OpenResetPasswordComplete + else -> OnboardingViewEvents.OpenResetPasswordComplete } _viewEvents.post(nextEvent) }, diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueExtensions.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueExtensions.kt index ea25d8ebcd..682cd96b56 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueExtensions.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueExtensions.kt @@ -31,6 +31,6 @@ fun SignMode.toAuthenticateAction(login: String, password: String, initialDevice } fun ThemeProvider.ftueBreakerBackground() = when (isLightTheme()) { - true -> R.drawable.bg_gradient_ftue_breaker + true -> R.drawable.bg_gradient_ftue_breaker false -> R.drawable.bg_color_background } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricAuthError.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricAuthError.kt index 1b7d35879e..7a293d022e 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricAuthError.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricAuthError.kt @@ -33,6 +33,6 @@ class BiometricAuthError(val code: Int, message: String) : Throwable(message) { val isAuthPermanentlyDisabledError: Boolean get() = code == BiometricPrompt.ERROR_LOCKOUT_PERMANENT companion object { - private val LOCKOUT_ERROR_CODES = arrayOf(BiometricPrompt.ERROR_LOCKOUT, BiometricPrompt.ERROR_LOCKOUT_PERMANENT) + private val LOCKOUT_ERROR_CODES = arrayOf(BiometricPrompt.ERROR_LOCKOUT, BiometricPrompt.ERROR_LOCKOUT_PERMANENT) } } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelper.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelper.kt index 1b510f5983..a34b284193 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelper.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/biometrics/BiometricHelper.kt @@ -73,26 +73,30 @@ class BiometricHelper @Inject constructor( /** * Returns true if a weak biometric method (i.e.: some face or iris unlock implementations) can be used. */ - val canUseWeakBiometricAuth: Boolean get() = - configuration.isWeakBiometricsEnabled && biometricManager.canAuthenticate(BIOMETRIC_WEAK) == BIOMETRIC_SUCCESS + val canUseWeakBiometricAuth: Boolean + get() = + configuration.isWeakBiometricsEnabled && biometricManager.canAuthenticate(BIOMETRIC_WEAK) == BIOMETRIC_SUCCESS /** * Returns true if a strong biometric method (i.e.: fingerprint, some face or iris unlock implementations) can be used. */ - val canUseStrongBiometricAuth: Boolean get() = - configuration.isStrongBiometricsEnabled && biometricManager.canAuthenticate(BIOMETRIC_STRONG) == BIOMETRIC_SUCCESS + val canUseStrongBiometricAuth: Boolean + get() = + configuration.isStrongBiometricsEnabled && biometricManager.canAuthenticate(BIOMETRIC_STRONG) == BIOMETRIC_SUCCESS /** * Returns true if the device credentials can be used to unlock (system pin code, password, pattern, etc.). */ - val canUseDeviceCredentialsAuth: Boolean get() = - configuration.isDeviceCredentialUnlockEnabled && biometricManager.canAuthenticate(DEVICE_CREDENTIAL) == BIOMETRIC_SUCCESS + val canUseDeviceCredentialsAuth: Boolean + get() = + configuration.isDeviceCredentialUnlockEnabled && biometricManager.canAuthenticate(DEVICE_CREDENTIAL) == BIOMETRIC_SUCCESS /** * Returns true if any system authentication method (biometric weak/strong or device credentials) can be used. */ @VisibleForTesting(otherwise = PRIVATE) - internal val canUseAnySystemAuth: Boolean get() = canUseWeakBiometricAuth || canUseStrongBiometricAuth || canUseDeviceCredentialsAuth + internal val canUseAnySystemAuth: Boolean + get() = canUseWeakBiometricAuth || canUseStrongBiometricAuth || canUseDeviceCredentialsAuth /** * Returns true if any system authentication method and there is a valid associated key. @@ -153,9 +157,9 @@ class BiometricHelper @Inject constructor( @SuppressLint("NewApi") @OptIn(ExperimentalCoroutinesApi::class) private fun authenticateInternal( - activity: FragmentActivity, - checkSystemKeyExists: Boolean, - cryptoObject: BiometricPrompt.CryptoObject? = null, + activity: FragmentActivity, + checkSystemKeyExists: Boolean, + cryptoObject: BiometricPrompt.CryptoObject? = null, ): Flow { if (checkSystemKeyExists && !isSystemAuthEnabledAndValid) return flowOf(false) @@ -189,9 +193,9 @@ class BiometricHelper @Inject constructor( @VisibleForTesting(otherwise = PRIVATE) internal fun authenticateWithPromptInternal( - activity: FragmentActivity, - cryptoObject: BiometricPrompt.CryptoObject? = null, - channel: Channel, + activity: FragmentActivity, + cryptoObject: BiometricPrompt.CryptoObject? = null, + channel: Channel, ): BiometricPrompt { val executor = ContextCompat.getMainExecutor(context) val callback = createSuspendingAuthCallback(channel, executor.asCoroutineDispatcher()) diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepository.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepository.kt index a8690f69d2..4a7bce8a52 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepository.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/crypto/LockScreenKeyRepository.kt @@ -36,7 +36,7 @@ class LockScreenKeyRepository( private val systemKeyAlias = "$baseName.system" private val pinCodeCrypto: KeyStoreCrypto by lazy { - keyStoreCryptoFactory.provide(pinCodeKeyAlias, keyNeedsUserAuthentication = false) + keyStoreCryptoFactory.provide(pinCodeKeyAlias, keyNeedsUserAuthentication = false) } private val systemKeyCrypto: KeyStoreCrypto by lazy { keyStoreCryptoFactory.provide(systemKeyAlias, keyNeedsUserAuthentication = true) diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt index 764da8cceb..0e6fdfb61e 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt @@ -114,15 +114,15 @@ class LockScreenFragment : VectorBaseFragment() { private fun handleEvent(viewEvent: LockScreenViewEvent) { when (viewEvent) { is LockScreenViewEvent.CodeCreationComplete -> lockScreenListener?.onPinCodeCreated() - is LockScreenViewEvent.ClearPinCode -> { + is LockScreenViewEvent.ClearPinCode -> { if (viewEvent.confirmationFailed) { lockScreenListener?.onNewCodeValidationFailed() } views.codeView.clearCode() } - is LockScreenViewEvent.AuthSuccessful -> lockScreenListener?.onAuthenticationSuccess(viewEvent.method) - is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method) - is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable) + is LockScreenViewEvent.AuthSuccessful -> lockScreenListener?.onAuthenticationSuccess(viewEvent.method) + is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method) + is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable) } } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt index a240af243a..39d0937323 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt @@ -94,7 +94,7 @@ class LockScreenViewModel @AssistedInject constructor( override fun handle(action: LockScreenAction) { when (action) { - is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value) + is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value) is LockScreenAction.ShowBiometricPrompt -> showBiometricPrompt(action.callingActivity) } } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/utils/DevicePromptCheck.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/utils/DevicePromptCheck.kt index fa1d7d5559..1760cd6c80 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/utils/DevicePromptCheck.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/utils/DevicePromptCheck.kt @@ -48,15 +48,15 @@ object DevicePromptCheck { * See [this OP forum thread](https://forums.oneplus.com/threads/oneplus-7-pro-fingerprint-biometricprompt-does-not-show.1035821/). */ private val isOnePlusDeviceWithNoBiometricUI: Boolean = - Build.BRAND.equals("OnePlus", ignoreCase = true) && - !onePlusModelsWithWorkingBiometricUI.contains(Build.MODEL) && - Build.VERSION.SDK_INT < Build.VERSION_CODES.R + Build.BRAND.equals("OnePlus", ignoreCase = true) && + !onePlusModelsWithWorkingBiometricUI.contains(Build.MODEL) && + Build.VERSION.SDK_INT < Build.VERSION_CODES.R /** * Some LG models don't seem to have a system biometric prompt at all. */ private val isLGDeviceWithNoBiometricUI: Boolean = - Build.BRAND.equals("LG", ignoreCase = true) && lgModelsWithoutBiometricUI.contains(Build.MODEL) + Build.BRAND.equals("LG", ignoreCase = true) && lgModelsWithoutBiometricUI.contains(Build.MODEL) /** * Check if this device is included in the list of devices with known Biometric Prompt issues. diff --git a/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingFragment.kt b/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingFragment.kt index d553c1a8ce..78c06d5969 100644 --- a/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/font/FontScaleSettingFragment.kt @@ -31,7 +31,7 @@ import javax.inject.Inject class FontScaleSettingFragment @Inject constructor( private val fontListController: FontScaleSettingController -) : VectorBaseFragment(), FontScaleSettingController.Callback { +) : VectorBaseFragment(), FontScaleSettingController.Callback { private val viewModel: FontScaleSettingViewModel by fragmentViewModel() diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt index 265cf3199e..b1a240e942 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt @@ -94,10 +94,10 @@ class SoftLogoutController @Inject constructor( } private fun buildForm(state: SoftLogoutViewState) = when (state.asyncHomeServerLoginFlowRequest) { - is Fail -> buildLoginErrorWithRetryItem(state.asyncHomeServerLoginFlowRequest.error) - is Success -> buildLoginSuccessItem(state) + is Fail -> buildLoginErrorWithRetryItem(state.asyncHomeServerLoginFlowRequest.error) + is Success -> buildLoginSuccessItem(state) is Loading, Uninitialized -> buildLoadingItem() - is Incomplete -> Unit + is Incomplete -> Unit } private fun buildLoadingItem() { @@ -116,11 +116,11 @@ class SoftLogoutController @Inject constructor( } private fun buildLoginSuccessItem(state: SoftLogoutViewState) = when (state.asyncHomeServerLoginFlowRequest.invoke()) { - LoginMode.Password -> buildLoginPasswordForm(state) - is LoginMode.Sso -> buildLoginSSOForm() + LoginMode.Password -> buildLoginPasswordForm(state) + is LoginMode.Sso -> buildLoginSSOForm() is LoginMode.SsoAndPassword -> disambiguateLoginSSOAndPasswordForm(state) - LoginMode.Unsupported -> buildLoginUnsupportedForm() - LoginMode.Unknown, null -> Unit // Should not happen + LoginMode.Unsupported -> buildLoginUnsupportedForm() + LoginMode.Unknown, null -> Unit // Should not happen } private fun buildLoginPasswordForm(state: SoftLogoutViewState) { @@ -148,12 +148,12 @@ class SoftLogoutController @Inject constructor( private fun disambiguateLoginSSOAndPasswordForm(state: SoftLogoutViewState) { when (state.loginType) { - LoginType.PASSWORD -> buildLoginPasswordForm(state) - LoginType.SSO -> buildLoginSSOForm() + LoginType.PASSWORD -> buildLoginPasswordForm(state) + LoginType.SSO -> buildLoginSSOForm() LoginType.DIRECT, LoginType.CUSTOM, LoginType.UNSUPPORTED -> buildLoginUnsupportedForm() - LoginType.UNKNOWN -> Unit + LoginType.UNKNOWN -> Unit } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt index 4286c12058..5b362690fa 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt @@ -110,6 +110,7 @@ class SpaceDirectoryController @Inject constructor( ?.filter { it.parentRoomId == (data.hierarchyStack.lastOrNull() ?: data.spaceId) } + ?.filterNot { it.isUpgradedRoom(data) } ?: emptyList() if (flattenChildInfo.isEmpty()) { @@ -209,4 +210,7 @@ class SpaceDirectoryController @Inject constructor( } } } + + private fun SpaceChildInfo.isUpgradedRoom(data: SpaceDirectoryState) = + data.knownRoomSummaries.any { it.roomId == childRoomId && it.versioningState.isUpgraded() } } diff --git a/vector/src/main/res/values-ar/strings.xml b/vector/src/main/res/values-ar/strings.xml index 9c436d24f0..044653f4ba 100644 --- a/vector/src/main/res/values-ar/strings.xml +++ b/vector/src/main/res/values-ar/strings.xml @@ -97,14 +97,14 @@ • الخوادِم المُطابقة لـ %s أُزيلت مِن قائمة الحظر. • الخوادِم المُطابقة لـ %s محظورة الآن. • خوادِم مُطابقة IP الحرفية مسموحة الآن. - يَّرتَ خادِم الـACLs لهذه الغُرفة. - غيَّرَ %s خادِم الـACLs لهذه الغُرفة. - • الخوادِم المطابقة للقيم الحرفية للـIP محظورة. - • الخوادِم المُطابقة لـ %s مسموحة. + لقد قمت بتغيير قائمة الوصول لهذه الغُرفة. + قام %s بتغيير قائمة الوصول (ACL) لهذه الغُرفة. + • الخوادِم المتطابقة من حيث بروتوكول الإنترنت (IP) المستخدم محظورة. + • الخوادِم المُطابقة لـِ %s مسموحة. • الخوادِم المُطابقة لـ %s محظورة. - • الخوادِم المطابقة للقيم الحرفية للـIP مسموحة. - عيَّنتَ خادِم الـACLs لهذه الغُرفة. - عيَّنَ %s خادِم الـACLs لهذه الغُرفة. + الخوادِم المتطابقة من حيث بروتوكول الإنترنت (IP) المستخدم مسموحة. + لقد قمت بتعيين قائمة التحكم بالوصول لهذه الغُرفة. + %s قام بتعيين قائمة التحكم بالوصول لهذه الغرفة. رقيتَ هُنا. رقّى %s هُنا. جعلتَ الرسائل المُستقبلية مرئية لـ %1$s diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index 9491ebed77..05d10b0f5f 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -21,7 +21,7 @@ %1$s ha vetat %2$s %1$s ha retirat la invitació de %2$s %1$s ha canviat la seva foto - %1$s ha establert la visibilitat de l\'històric futur de la sala a %2$s + %1$s ha activat la visualització de l\'històric de la sala (a partir d\'ara) a %2$s tots els participants de la sala, des de que s\'hi uneixen. qualsevol. (també ha canviat la foto) @@ -153,7 +153,7 @@ %s ha actualitzat aquesta sala. Has establert la visibilitat dels missatges futurs a %1$s %1$s ha establert la visibilitat dels missatges futurs a %2$s - Has establert la visibilitat de l\'històric futur de la sala a %1$s + Has establert la visibilitat de l\'històric de la sala (a partir d\'ara) a %1$s Has finalitzat la trucada. Has respost a la trucada. Has enviat dades per configurar la trucada. @@ -1055,7 +1055,7 @@ Utilitza el xifrat per mantenir els teus xats privats Aquest xat és teu. Apropia-te\'n. Filtra xats… - Inici de l\'històric del xat personal amb %s. + Inici de l\'històric del xat directe amb %s. L\'administrador del servidor ha desactivat el xifrat d\'extrem a extrem per defecte en sales privades i en xats directes. Xat personal Els missatges d\'aquí estan xifrats d\'extrem a extrem. @@ -1064,7 +1064,7 @@ Crea un nou xat personal Envia un nou missatge Xats directes - Els missatges d\'aquesta sala estan xifrats d\'extrem a extrem. + Els missatges d\'aquest xat estan xifrats d\'extrem a extrem. Mostra els esdeveniments amagats a la cronologia No s\'ha pogut enviat el suggeriment (%s) Gràcies, el suggeriment s\'ha enviat correctament @@ -2482,7 +2482,7 @@ Obre càmera Mostra els contorns dels missatges Actualitzada fa %1$s - Implementació temporal: les ubicacions persisteixen a l\'historial de la sala + Implementació temporal: les ubicacions persisteixen a l\'històric de la sala Coses en aquest espai Reprodueix immediatament les imatges animades a la cronologia Deixa de compartir @@ -2529,4 +2529,10 @@ \'Endpoint\' registrat correctament al servidor. Registre d\'endpoint Següent - + Quan convidis algú a una sala xifrada que comparteix l\'històric de missatges, aquest serà visible. + Els resultats es mostraran quan acabi l\'enquesta + MSC3061: Compartició de claus de sala per missatges antics + Envia un primer missatge per convidar %s a parlar + Els missatges d\'aquest xat seran xifrats d\'extrem a extrem. + Crea + \ No newline at end of file diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index c15de7cc0d..cd66940316 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2577,4 +2577,10 @@ Koncový bod byl úspěšně zaregistrován na domovském serveru. Registrace koncového bodu Další - + Výsledky se zobrazí po ukončení hlasování + Při pozvání do šifrované místnosti, která sdílí historii, bude zašifrovaná historie viditelná. + MSC3061: Sdílení klíčů místnosti pro minulé zprávy + Odesláním první zprávy pozvete %s do místnosti + Zprávy v této místnosti budou koncově šifrovány. + Přejít + \ No newline at end of file diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bf69883e14..fcb82889f5 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2528,4 +2528,5 @@ Profil personalisieren ${app_name} ist auch für den Arbeitsplatz geeignet. Die sichersten Organisationen der Welt vertrauen darauf. Threads sind noch in Arbeit, und es stehen neue, aufregende Funktionen an, wie z. B. verbesserte Benachrichtigungen. Wir würden uns sehr über Dein Feedback freuen! - + Nachrichten in diesem Chat werden End-zu-End-Verschlüsselt + \ No newline at end of file diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index af4c9d3b4c..80881f45c0 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -1705,7 +1705,7 @@ Kas sa unustasid või kaotasid kõik võimalused taastada ligipääsu oma kontole\? Lähtesta kõik seadistused Sina liitusid. %s liitus. - See jututuba on läbivalt krüptitud. + See vestlus on läbivalt krüptitud. Lahku Seadistused Sõnumid siin jututoas kasutavad läbivat krüptimist. @@ -2520,4 +2520,10 @@ Sünkroniseerimine taustal Google\'i teenused Vali teavituste laadimise viis - + Tulemused on näha siis, kui küsitlus on lõppenud + Kutsudes osalejaid krüptitud jututuppa, kus ajaloo jagamine on lubatud, on vanad sõnumid loetavad. + MSC3061: Minevikus saadetud sõnumite lugemiseks vajalike krüptovõtmete jagamine jututoas + Saada oma esimene sõnum kutsudes %s vestlusesse + See vestlus saab olema läbivalt krüptitud. + Mine + \ No newline at end of file diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 95f9bedfae..a8dbe72b74 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -1095,7 +1095,7 @@ %s پیوست. اتاق را ساخته و پیکربندی کردید. رمزنگاری به کار نیفتاده - پیام‌های این اتاق، رمزنگاری سرتاسری دارند. + پیام‌های این گپ، رمزنگاری سرتاسری دارند. پیام‌های این اتاق رمزنگاری سرتاسری دارند. در نمایهٔ کاربران تأییدشان کرده و بیش‌تر بیاموزید. رمزنگاری به کار افتاد هنگام ارتقای اتاق‌ها @@ -1213,7 +1213,7 @@ شکست در ثبت ژتون FCM در کارساز خانگی: \n%1$s ژتون FCM با موفقیت در کارساز خانگی ثبت شد. - ثبت توکن + ثبت ژتون افزودن حساب کاربری [%1$s] \nاین خطا خارج از مهار ${app_name} است. هیچ حساب گوگلی روی تلفن نیست. لطفاً مدیر حساب را گشوده و حساب گوگلی بیفزایید. @@ -1221,11 +1221,11 @@ \nاین خطا خارج از مهار ${app_name} است و ممکن است به دلایل مختلفی رخ داده باشد. ممکن است اگر بعداً دوباره تلاش کنید، کار کند. می‌توانید بررسی کنید که مصرف دادهٔ خدمات پلی گوگل در تنظیمات سامانه محدود نشده باشد یا ساعت افزاره‌تان درست باشد. همچنین ممکن است روی رام‌های سفارشی اتفاق بیفتد. [%1$s] \nاین خطا، خارج از مهار ${app_name} است و طبق گفتهٔ گوگل، نشانگر ثبت بیش‌از حد کاره‌ها در FCM است. خطا فقط در مواردی که تعداد خیلی زیادی کاره وجود داشته باشد رخ می‌دهد، پس کاربران معمولی نباید تحت تأثیر قرار گیرند. - بازیابی توکن FCM با مشکل مواجه شد: + شکست در بازیابی ژتون FCM: \n%1$s - توکن FCM با موفقیت بازیابی شد: + ژتون FCM با موفقیت بازیابی شد: \n%1$s - توکن Firebase + ژتون فایربیس مشکل Google Play Services را برطرف کنید المنت برای ارسال آگاهی‌ها از خدمات پلی گوگل استفاده می‌کند اما به نظر می‌رسد به درستی پیکربندی نشده است: \n%1$s @@ -1494,7 +1494,7 @@ قطع ارتباط با سرور هویت‌سنجی به این معنی است که توسط کاربران دیگر قابل شناسایی نخواهید بود و نمی توانید دیگران را از طریق ایمیل یا تلفن دعوت کنید. در حال استفاده از کارساز هویتی نیستید. برای کشق و قابل کشف بودن به دست آشنایان موجودی که می‌شناسید، یک کارساز هویت در زیر پیکربندی کنید. دارید برای کشف و قابل کشف بودن به دست آشنایان موجودی که می‌شناسید از %1$s استفاده می‌کنید. - ثبت توکن + ثبت ژتون فرمت: آدرس: نام نشست: @@ -2521,4 +2521,18 @@ بازنشانی روش آگاهی برچسب نمایه: بعدی - + لطفاً به خاطر داشته باشید: این یک ویژگی آزمایشگاهی با پیاده‌سازی موقّتی است. یعنی نخواهید توانست تاریخجهٔ مکانتان را حذف کرده و کاربران پیش‌رفته خواهند توانست حتا پس از پایان هم‌رسانی مکان زنده‌تان با این اتاق، تاریخچهٔ مکانتان را ببینند. + نتوانست نقطهٔ پایانی را بیابد. + نقطهٔ پایانی کنونی: %s + نقطهٔ پایانی + هنگام پایان نظرسنجی، نتایج نمایان خواهند شد + هنگام دعوت به اتاقی رمزشده که تاریخچه‌ای هم‌رسانده دارد، تاریخچهٔ رمز شده نمایان خواهد بود. + MSC3061: هم‌رسانی کلیدهای اتاق برای پیام‌های گذشته + نخستین پیامتان را برای دعوت %s به گپ بفرستید + پیام‌های این گپ رمزنگاری سرتاسری خواهند شد. + رفتن + شکست در ثبت ژتون نقطهٔ پایانی روی کارساز خانگی: +\n%1$s + نقطهٔ پایانی با موفّقیت روی کارساز خانگی ثبت شد. + ثبت نقطهٔ پایانی + \ No newline at end of file diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 01852278ef..3cfbd5f9bd 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2529,4 +2529,10 @@ Le point de connexion a été correctement enregistré sur le serveur d’accueil. Enregistrement du point de connexion Suivant - + Les résultats seront visibles lorsque le sondage sera terminé + Lors de l’invitation dans un salon chiffré qui partage son historique, son historique chiffré sera visible. + MSC3061 : Partage des clés du salon pour les messages passés + Envoyez votre premier message pour inviter %s à discuter + Les messages de ce salon seront chiffrés de bout en bout. + C’est parti + \ No newline at end of file diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 99caed9211..dc9e17fc75 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -1607,7 +1607,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Még nem adtál hozzá a fiókodhoz email címet Email címek Még nem adtál hozzá telefonszámot a fiókodhoz - Az üzenetek ebben a szobában végpontok közötti titkosítással védettek. + Az üzenetek ebben a beszélgetésben végpontok közötti titkosítással védettek. Kép hozzáadása Adj meg egy témát %s, hogy a többiek tudják, miről van szó ebben a szobában! @@ -2318,7 +2318,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze A változások életbelépéséhez indítsd újra az alkalmazást. LaTeX matematikai szintaxis engedélyezése Nem léphetsz be ebbe a szobába - Az ön beszélgetései csak az öné. + Birtokold a beszélgetéseid. Titkosítás visszafejtési hiba esemény alkalmával a rendszer automatikusan elküldi a logokat Titkosítás visszafejtési hibák automatikus jelentése. Szavazás létrehozása @@ -2436,7 +2436,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Válassz egy megjelenítési nevet A fiókod elkészült: %s. Gratulálunk! - Vigyél haza + A kezdőlapra Profil személyre szabása Tiltás Élő földrajzi helyzet meghatározás betöltése… @@ -2499,4 +2499,40 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze mperc perc ó - + Földrajzi hely megosztás engedélyezése + Figyelem: ez a labor lehetőség egy átmeneti megvalósítás. Ez azt jelenti, hogy a szobába már elküldött helyadatok az élő hely megosztás leállítása után is hozzáférhetők maradnak a szobában. + Élő földrajzi hely megosztása + Jelenlegi átjáró: %s + Átjáró (gateway) + Nem található végpont. + Jelenlegi végpont: %s + Végpont + Jelenleg használatban: %s. + Metódus + + %d beállítás található. + %d beállítás található. + + A háttér szinkronizációs szolgáltatástól eltérő beállítási lehetőség nem érhető el. + A Google Play szolgáltatástól eltérő beállítási lehetőség nem érhető el. + Elérhető beállítások + Értesítési beállítások + Szinkronizálás a háttérben + Google szolgáltatások + Válaszd ki, hogyan szeretnél értesítéseket kapni + Az eredmény a szavazás végeztével válik láthatóvá + Ha olyan titkosított szobába hívsz meg valakit ahol a régi üzenetek megosztása engedélyezett a régi titkosított üzenetek is láthatóak lesznek a meghívott számára. + MSC3061: Szoba kulcsok megosztása a régi üzenetekhez + A biometrikus azonosítást nem lehet engedélyezni. + A biometrikus azonosítás kikapcsolásra került mivel egy új biometrikus azonosítási metódus került hozzáadásra. Újra engedélyezheted a Beállításokban. + Az első üzeneteddel hívd meg ide őt: %s + Az üzenetek ebben a beszélgetésben végpontok közötti titkosítással lesznek védve. + Értesítési metódus visszaállítása + Profil címke: + Menj + Végpont token regisztrációja sikertelen a Matrix-kiszolgálón: +\n%1$s + Végpont sikeresen regisztrálva lett a matrix szerveren. + Végpont regisztráció + Következő + \ No newline at end of file diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 104203bf32..11752f934f 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2032,7 +2032,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda membuat dan mengatur ruangan ini. %s membuat dan mengatur ruangan ini. Enkripsi tidak diaktifkan - Pesan di ruangan ini dienkripsi secara ujung-ke-ujung. + Pesan di obrolan ini dienkripsi secara ujung-ke-ujung. Pesan di ruangan ini dienkripsi secara ujung-ke-ujung. Pelajari lebih lanjut & verifikasi pengguna di profil mereka. Enkripsi diaktifkan Jika Anda batalkan, Anda mungkin kehilangan pesan terenkripsi dan data Anda jika Anda kehilangan akses ke login Anda. @@ -2483,4 +2483,10 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Endpoint berhasil terdaftar ke homeserver. Pendaftaran Endpoint Lanjut - + Hasil akan ditampilkan ketika pemungutan suara berakhir + Ketika mengundang ke ruangan terenkripsi yang juga membagikan riwayat, riwayat terenkripsi akan dapat dilihat. + MSC3061: Pembagian kunci ruangan untuk pesan lama + Kirim pesan pertama Anda untuk mengundang %s ke obrolan + Pesan di obrolan ini akan dienkripsi secara ujung-ke-ujung. + Mulai + \ No newline at end of file diff --git a/vector/src/main/res/values-is/strings.xml b/vector/src/main/res/values-is/strings.xml index 88234a6364..53af7bff5c 100644 --- a/vector/src/main/res/values-is/strings.xml +++ b/vector/src/main/res/values-is/strings.xml @@ -764,7 +764,7 @@ Uppfærsla dulritunar tiltæk Sendir skilaboð sem óbreyttur texti án þess að túlka það sem markdown Dulritun ekki virk - Skilaboð í þessari spjallrás eru enda-í-enda dulrituð. + Skilaboð í þessu spjalli eru enda-í-enda dulrituð. Kerfisstjóri netþjónsins þíns hefur lokað á sjálfvirka dulritun í einkaspjallrásum og beinum skilaboðum. Stillingar spjallrásar Skilaboð í þessari spjallrás eru ekki enda-í-enda dulrituð. @@ -1292,7 +1292,7 @@ Lokið Tókst ! (Ítarlegt) - %d+ + +%d %1$s: %2$s fella saman fletta út @@ -2017,4 +2017,4 @@ Prófaðu það Gera óvirkt Upphafleg samstillingarbeiðni - + \ No newline at end of file diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 3879e5a13c..140b63e4c8 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -1692,7 +1692,7 @@ Reimposta tutto Hai dimenticato o perso tutte le opzioni di ripristino\? Reimposta tutto Sei entrato. - I messaggi in questa stanza sono crittografati E2E. + I messaggi in questa conversazione sono cifrati end-to-end. Esci Impostazioni I messaggi qui sono cifrati E2E. @@ -2520,4 +2520,10 @@ Endpoint registrato con successo sull\'homeserver. Registrazione endpoint Avanti - + I risultati saranno visibili quando il sondaggio sarà terminato + Quando si invita in una stanza crittografata che condivide la cronologia, la cronologia cifrata sarà visibile. + MSC3061: Condivisione chiavi stanza per messaggi passati + Invia il primo messaggio per invitare %s a parlare + I messaggi in questa conversazione saranno cifrati end-to-end. + Vai + \ No newline at end of file diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 9b5591d8d0..a9d9dd3658 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -1927,7 +1927,7 @@ %s heeft de kamer gemaakt en geconfigureerd. De versleuteling die door deze kamer wordt gebruikt, wordt niet ondersteund Versleuteling niet ingeschakeld - Berichten in deze kamer zijn end-to-end-versleuteld. + Berichten in deze chat zijn end-to-end-versleuteld. Berichten in deze kamer zijn eind-tot-eind-versleuteld. Lees meer en verifieer persoon in hun profiel. Als u nu annuleert, kunt u versleutelde berichten en gegevens kwijtraken als u de toegang tot uw aanmeldingen verliest. \n @@ -2529,4 +2529,10 @@ Eindpunt succesvol geregistreerd bij server. Registratie van eindpunt Volgende - + Resultaten zijn zichtbaar wanneer de poll is afgelopen + Bij het uitnodigen in een versleutelde ruimte die geschiedenis deelt, is de versleutelde geschiedenis zichtbaar. + MSC3061: Kamersleutels delen voor eerdere berichten + Stuur uw eerste bericht om %s uit te nodigen om te chatten + Berichten in deze chat worden eind-tot-eind versleuteld. + Ga + \ No newline at end of file diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index 26e85f2473..a9d1df49d8 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -1163,9 +1163,9 @@ Wyślij obrazów w oryginalnym rozmiarze Potwierdź Usunięcie - Jesteś pewny(-na), że chcesz usunąć to wydarzenie\? Jeżeli usuniesz nazwę pokoju lub zmienisz temat, wciąż będzie możliwe cofnięcie zmiany. + Czy na pewno chcesz usunąć to wydarzenie\? Pamiętaj, że skasowanie nazwy pokoju lub zmiana jego tematu może czasem je przywrócić. Podaj przyczynę - Przyczyna reakcji + Powód usunięcia Wydarzenie usunięte przez użytkownika, przyczyna: %1$s Wydarzenie moderowane przez administratora pokoju, przyczyna: %1$s Klucze są już aktualne! @@ -2605,4 +2605,4 @@ Dostępni dostawcy Dostawca powiadomień Wybierz, którego dostawcy powiadomień push chcesz używać - + \ No newline at end of file diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index edc4163d0c..9ddfa08aa4 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -1810,7 +1810,7 @@ Ahoj, ozvi sa mi na ${app_name}: %s Nemohli sme vytvoriť vašu priamu správu. Skontrolujte používateľov, ktorých chcete pozvať, a skúste to znova. Kvôli end-to-end šifrovaniu sa môže stať, že budete musieť chvíľu počkať, kým vám od niekoho príde správa, pretože vám neboli správne odoslané šifrovacie kľúče. - Správy v tejto miestnosti sú šifrované od vás až k príjemcovi. + Správy v tejto konverzácii sú šifrované od vás až k príjemcovi. Správy v tejto miestnosti sú end-to-end šifrované. Zistite viac a overte používateľov v ich profile. Správca vášho servera predvolene vypol end-to-end šifrovanie v súkromných miestnostiach a v priamych správach. Správy s týmto používateľom sú end-to-end šifrované a tretie strany ich nemôžu čítať. @@ -2577,4 +2577,10 @@ Koncové zariadenie sa úspešne zaregistrovalo na domovský server. Registrácia koncového bodu Ďalej - + Výsledky budú viditeľné po ukončení ankety + Pri pozvaní do zašifrovanej miestnosti, ktorá zdieľa históriu, bude zašifrovaná história viditeľná. + MSC3061: Zdieľanie kľúčov od miestnosti pre staršie správy + Odošlite svoju prvú správu a pozvite %s do konverzácie + Správy v tejto miestnosti sú šifrované od vás až k príjemcovi. + Spustiť + \ No newline at end of file diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 84e90da44b..29ecdfe895 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -1706,7 +1706,7 @@ Lämna Återställ allt Du gick med. - Meddelanden i det här rummet är totalsträckskrypterade. + Meddelanden i den här chatten är totalsträckskrypterade. Inställningar Meddelanden här är totalsträckskrypterade. \n @@ -2529,4 +2529,10 @@ \n%1$s Lyckades registrera ändpunkten hos hemservern. Ändpunktsregistrering - + Resultat kommer att synas när omröstningen avslutas + När du bjuder in i ett krypterat rum som delar historik, så kommer krypterad historik att vara synlig. + MSC3061: Delar rumsnycklar för tidigare meddelanden + Skicka ditt första meddelande för att bjuda in %s att chatta + Meddelanden i den här chatten kommer att vara totalsträckskrypterade. + + \ No newline at end of file diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index a5b9571748..ed7a2c7438 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -22,7 +22,7 @@ %s починає відеовиклик. %s розпочинає голосовий виклик. %s відповідає на виклик. - %s завершує дзвінок. + %s завершує виклик. %1$s робить майбутню історію кімнати видимою для %2$s всіх учасників кімнати, з моменту їх запрошення. всіх учасників кімнати, з моменту їх приєднання. @@ -135,7 +135,7 @@ Ви зробили майбутню історію кімнати видимою для %1$s Ви зробили майбутні повідомлення видимими для %1$s %1$s робить майбутні повідомлення видимими для %2$s - Ви завершили дзвінок. + Ви завершили виклик. Ви відповіли на виклик. Ви надіслали дані для налаштування виклику. %s надсилає дані для налаштування виклику. @@ -230,8 +230,10 @@ Виконується виклик… Абонент не відповідає. Інформація - Для здійснення аудіодзвінків потрібен доступ до мікрофону. - Для здійснення відеодзвінків потрібен доступ до камери та мікрофону.\n\nБудь ласка, надайте його у наступних виринаючих вікнах, щоб мати змогу їх здійснити. + Для здійснення аудіовикликів потрібен доступ до мікрофона. + Для здійснення відеовикликів потрібен доступ до камери та мікрофону. +\n +\nНадайте його у наступних спливних вікнах, щоб мати змогу їх здійснити. ТАК НІ Продовжити @@ -406,7 +408,7 @@ Гучно Зашифроване повідомлення Використовувати рідну камеру - Щойно доданий вами пристрій \'%s\' править ключі шифрування. + Щойно доданий вами сеанс «%s», який запитує ключі шифрування. Ваш незвірений пристрій «%s» вимагає ключі шифрування. Почати перевірку Помилка виконання команди @@ -600,13 +602,13 @@ Пропустити Не вдалося видалити віджет Не вдалося додати віджет - Ви не можете здійснити дзвінок із самим собою + Ви не можете викликати самих себе Почати аудіо-зустріч Почати відеозустріч - У вас немає повноважень розпочати дзвінок - У вас немає повноважень на дзвінок у цій кімнаті - У вас немає повноважень розпочати груповий виклик - У вас немає повноважень розпочати груповий виклик у цій кімнаті + У вас немає дозволу розпочати виклик + У вас немає дозволу розпочати виклик у цій кімнаті + У вас немає дозволу розпочати груповий виклик + У вас немає дозволу розпочати груповий виклик у цій кімнаті Скинути Відхилити Грати @@ -628,7 +630,7 @@ Мені не потрібні мої зашифровані повідомлення Скасувати зміни Помилка SSL. - Ви не можете здійснити дзвінок із самим собою, дочекайтесь, доки інші учасники приймуть ваше запрошення + Ви не можете викликати себе самих, дочекайтесь, доки інші учасники погодяться на ваше запрошення ФАЙЛИ У цій кімнаті немає медіа МЕДІА @@ -1005,9 +1007,9 @@ \n \nВи можете будь-коли змінити цю дію в загальних налаштуваннях. Нехтувати користувача - Понизити - Ви не зможете скасувати цю зміну, оскільки понижуєте свої права, якщо ви останній привілейований користувач у кімнаті, неможливо буде повернути собі привілеї. - Понизитися\? + Зменшити + Ви не зможете скасувати цю зміну, оскільки зменшуєте свої повноваження, якщо ви останній привілейований користувач у кімнаті, неможливо буде повернути собі повноваження. + Зменшити свої повноваження\? Дозволити доступ до ваших контактів. Щоб сканувати QR-код необхідно дозволити доступ до камери. Триває відеовиклик… @@ -1074,7 +1076,7 @@ Повідомлення в цій кімнаті не захищено наскрізним шифруванням. Повідомлення тут не захищено наскрізним шифруванням. Увімкнути наскрізне шифрування… - Повідомлення в цій кімнаті захищені наскрізним шифруванням. + Повідомлення в цій бесіді захищені наскрізним шифруванням. Звірити цей сеанс Звірте цей сеанс, щоб позначити його надійним та надати йому доступ до зашифрованих повідомлень. Якщо ви не входили в цей сеанс, ваш обліковий запис може бути зламано: Назва або ID (#example:matrix.org) @@ -1152,8 +1154,8 @@ Наліпка Використовувати ботів, мости, віджети та пакунки наліпок Зв\'язок із сервером втрачено - Не знайдено жодної правки - Історія правок + Виправлень не знайдено + Історія виправлень Рівень довіри Не довірений Довірений @@ -2461,7 +2463,7 @@ З ким ви спілкуватиметеся найчастіше\? Ви вже переглядаєте цю гілку! Переглянути у кімнаті - Відповісти у гілку + Відповісти в гілці Команду «%s» розпізнано, але вона не підтримується в гілках. З гілки Порада: Торкніться й утримуйте повідомлення і виберіть «%s». @@ -2623,4 +2625,10 @@ Кінцеву точку успішно зареєстровано на домашньому сервері. Реєстрація кінцевої точки Далі - + Результати будуть видимі після завершення опитування + Коли запросити когось у зашифровану кімнату, яка поширює історію, зашифрована історія буде видимою. + MSC3061: Поширення ключів кімнати для минулих повідомлень + Надішліть своє перше повідомлення, щоб запросити %s до бесіди + Повідомлення в цій бесіді будуть захищені наскрізним шифруванням. + Уперед + \ No newline at end of file diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 89b2a723e1..c04e293787 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -1671,7 +1671,7 @@ 忘記或遺失所有復原選項?重設所有東西 您已加入。 %s 已加入。 - 此聊天室中的訊息有端到端加密。 + 此聊天中的訊息有端到端加密。 離開 設定 這裡的訊息有端到端加密。 @@ -2481,4 +2481,10 @@ 端點成功註冊至家伺服器。 端點註冊 下一步 - + 結果將在投票結束時可見 + 在分享歷史的加密聊天室中邀請時,加密歷史會是可見的。 + MSC3061:為過去的訊息分享聊天室金鑰 + 傳送您的第一則訊息以邀請 %s 來聊天 + 此聊天中的訊息將會是端到端加密。 + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 333a626179..ed0cf691e2 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3121,6 +3121,8 @@ Stop sharing Updated %1$s ago + You don’t have permission to share live location + You need to have the right permissions in order to share live location in this room. Share location Show Message bubbles diff --git a/vector/src/test/java/org/matrix/android/sdk/api/session/room/model/VersioningStateTest.kt b/vector/src/test/java/org/matrix/android/sdk/api/session/room/model/VersioningStateTest.kt new file mode 100644 index 0000000000..473918d179 --- /dev/null +++ b/vector/src/test/java/org/matrix/android/sdk/api/session/room/model/VersioningStateTest.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.room.model + +import org.amshove.kluent.shouldBe +import org.junit.Test + +internal class VersioningStateTest { + + @Test + fun `when VersioningState is NONE, then isUpgraded returns false`() { + val versioningState = VersioningState.NONE + + val isUpgraded = versioningState.isUpgraded() + + isUpgraded shouldBe false + } + + @Test + fun `when VersioningState is UPGRADED_ROOM_NOT_JOINED, then isUpgraded returns true`() { + val versioningState = VersioningState.UPGRADED_ROOM_NOT_JOINED + + val isUpgraded = versioningState.isUpgraded() + + isUpgraded shouldBe true + } + + @Test + fun `when VersioningState is UPGRADED_ROOM_JOINED, then isUpgraded returns true`() { + val versioningState = VersioningState.UPGRADED_ROOM_JOINED + + val isUpgraded = versioningState.isUpgraded() + + isUpgraded shouldBe true + } +}