diff --git a/changelog.d/6776.bugfix b/changelog.d/6776.bugfix
new file mode 100644
index 0000000000..ceb1d52ebf
--- /dev/null
+++ b/changelog.d/6776.bugfix
@@ -0,0 +1 @@
+[App Layout] Recents carousel now scrolled to first position when new item added to or moved to this position
diff --git a/changelog.d/6779.misc b/changelog.d/6779.misc
new file mode 100644
index 0000000000..70eda0eb2f
--- /dev/null
+++ b/changelog.d/6779.misc
@@ -0,0 +1 @@
+[Modules] Lifts the application variants to the app module
diff --git a/changelog.d/7077.wip b/changelog.d/7077.wip
new file mode 100644
index 0000000000..907993c76f
--- /dev/null
+++ b/changelog.d/7077.wip
@@ -0,0 +1 @@
+[Device management] Session details screen
diff --git a/changelog.d/7102.bugfix b/changelog.d/7102.bugfix
new file mode 100644
index 0000000000..73d1bbc7d6
--- /dev/null
+++ b/changelog.d/7102.bugfix
@@ -0,0 +1 @@
+Fixes crash when quickly double clicking FABs in the new app layout
diff --git a/changelog.d/7103.bugfix b/changelog.d/7103.bugfix
new file mode 100644
index 0000000000..12a07b79e5
--- /dev/null
+++ b/changelog.d/7103.bugfix
@@ -0,0 +1 @@
+Fixes space list and new chat bottom sheets showing too small in New App Layout (especially evident in landscape)
diff --git a/changelog.d/7121.wip b/changelog.d/7121.wip
new file mode 100644
index 0000000000..2081b0d77a
--- /dev/null
+++ b/changelog.d/7121.wip
@@ -0,0 +1 @@
+Create DM room only on first message - Fix glitch in the room list
diff --git a/changelog.d/7122.bugfix b/changelog.d/7122.bugfix
new file mode 100644
index 0000000000..f088eed4b0
--- /dev/null
+++ b/changelog.d/7122.bugfix
@@ -0,0 +1 @@
+[App Layout] Room leaving prompt dialog now waits user to confirm leaving before do so
diff --git a/changelog.d/7142.misc b/changelog.d/7142.misc
new file mode 100644
index 0000000000..d3424185e4
--- /dev/null
+++ b/changelog.d/7142.misc
@@ -0,0 +1 @@
+Pulling no longer hosted im.dlg:android-dialer directly into the repository and removing legacy support library usages
diff --git a/coverage.gradle b/coverage.gradle
index 716f9b7cc7..2c0af25368 100644
--- a/coverage.gradle
+++ b/coverage.gradle
@@ -81,11 +81,11 @@ task generateCoverageReport(type: JacocoReport) {
task unitTestsWithCoverage(type: GradleBuild) {
// the 7.1.3 android gradle plugin has a bug where enableTestCoverage generates invalid coverage
startParameter.projectProperties.coverage = [enableTestCoverage: false]
- tasks = [':vector:testGplayDebugUnitTest', ':matrix-sdk-android:testDebugUnitTest']
+ tasks = ['testDebugUnitTest']
}
task instrumentationTestsWithCoverage(type: GradleBuild) {
startParameter.projectProperties.coverage = [enableTestCoverage: true]
startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui'
- tasks = [':vector-app:connectedGplayDebugAndroidTest', ':vector:connectedGplayDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
+ tasks = [':vector-app:connectedGplayDebugAndroidTest', ':vector:connectedDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
}
diff --git a/dependencies.gradle b/dependencies.gradle
index c7b441738b..9641a63f26 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -15,7 +15,7 @@ def gradle = "7.1.3"
def kotlin = "1.6.21"
def kotlinCoroutines = "1.6.4"
def dagger = "2.42"
-def appDistribution = "16.0.0-beta03"
+def appDistribution = "16.0.0-beta04"
def retrofit = "2.9.0"
def arrow = "0.8.2"
def markwon = "4.6.2"
diff --git a/gradle.properties b/gradle.properties
index 2af9214ed5..0e561faa8d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -12,6 +12,7 @@ org.gradle.jvmargs=-Xmx4g -Xms512M -XX:MaxPermSize=2048m -XX:MaxMetaspaceSize=1g
org.gradle.configureondemand=true
org.gradle.parallel=true
org.gradle.vfs.watch=true
+org.gradle.caching=true
# Android Settings
android.enableJetifier=true
diff --git a/library/ui-strings/src/main/res/values-ar/strings.xml b/library/ui-strings/src/main/res/values-ar/strings.xml
index 073f961cb6..70b9a33ab5 100644
--- a/library/ui-strings/src/main/res/values-ar/strings.xml
+++ b/library/ui-strings/src/main/res/values-ar/strings.xml
@@ -320,7 +320,7 @@
السمة
خطأ في فكّ التعمية
اسم الجهاز
- معرّف الجهاز
+ معرّف الجهاز
مفتاح الجهاز
صدّر مفاتيح الغرفة
صدّر المفاتيح إلى ملف محلي
diff --git a/library/ui-strings/src/main/res/values-bg/strings.xml b/library/ui-strings/src/main/res/values-bg/strings.xml
index b29823040f..d3e9e599bc 100644
--- a/library/ui-strings/src/main/res/values-bg/strings.xml
+++ b/library/ui-strings/src/main/res/values-bg/strings.xml
@@ -396,7 +396,7 @@
Тема
Грешка при разшифроване
Публично име
- Сесийно ID
+ Сесийно ID
Ключ на устройство
Експортирай E2E ключове за стая
Експортиране на ключове за стая
diff --git a/library/ui-strings/src/main/res/values-bn-rBD/strings.xml b/library/ui-strings/src/main/res/values-bn-rBD/strings.xml
index 2f068f1bf8..7897da934e 100644
--- a/library/ui-strings/src/main/res/values-bn-rBD/strings.xml
+++ b/library/ui-strings/src/main/res/values-bn-rBD/strings.xml
@@ -789,7 +789,7 @@
রুমের কুঞ্জিগুলি এক্সপোর্ট করুন
শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন
সেশানের কুঞ্জি
- আইডি
+ আইডি
সর্বজনীন নাম
ডিক্রিপশন সমস্যা
থিম
diff --git a/library/ui-strings/src/main/res/values-bn-rIN/strings.xml b/library/ui-strings/src/main/res/values-bn-rIN/strings.xml
index 828bc3bd34..56bde36977 100644
--- a/library/ui-strings/src/main/res/values-bn-rIN/strings.xml
+++ b/library/ui-strings/src/main/res/values-bn-rIN/strings.xml
@@ -693,7 +693,7 @@
ডিক্রিপশন সমস্যা
সর্বজনীন নাম
- আইডি
+ আইডি
সেশানের কুঞ্জি
শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন
diff --git a/library/ui-strings/src/main/res/values-ca/strings.xml b/library/ui-strings/src/main/res/values-ca/strings.xml
index e23c375084..3abd45e2d3 100644
--- a/library/ui-strings/src/main/res/values-ca/strings.xml
+++ b/library/ui-strings/src/main/res/values-ca/strings.xml
@@ -448,7 +448,7 @@
Tema
Error al desxifrar
Nom públic
- ID de sessió
+ ID de sessió
Clau de sessió
Exporta les claus de la sala E2E
Exporta les claus de la sala
diff --git a/library/ui-strings/src/main/res/values-cs/strings.xml b/library/ui-strings/src/main/res/values-cs/strings.xml
index 4ad9cf8e30..8316eab2c3 100644
--- a/library/ui-strings/src/main/res/values-cs/strings.xml
+++ b/library/ui-strings/src/main/res/values-cs/strings.xml
@@ -635,7 +635,7 @@
Motiv vzhledu
Chyba dešifrování
Veřejné jméno
- ID relace
+ ID relace
Klíč relace
Export E2E klíčů místností
Export klíčů místností
diff --git a/library/ui-strings/src/main/res/values-de/strings.xml b/library/ui-strings/src/main/res/values-de/strings.xml
index e49bb8ac78..827311bde6 100644
--- a/library/ui-strings/src/main/res/values-de/strings.xml
+++ b/library/ui-strings/src/main/res/values-de/strings.xml
@@ -418,7 +418,7 @@
Als Hauptadresse aufheben
Entschlüsselungsfehler
Öffentlicher Name
- Sitzungs-ID
+ Sitzungs-ID
Sitzungsschlüssel
Ende-zu-Ende-Raumschlüssel exportieren
Raumschlüssel exportieren
diff --git a/library/ui-strings/src/main/res/values-el/strings.xml b/library/ui-strings/src/main/res/values-el/strings.xml
index 092a01bff4..f4973f4b95 100644
--- a/library/ui-strings/src/main/res/values-el/strings.xml
+++ b/library/ui-strings/src/main/res/values-el/strings.xml
@@ -172,7 +172,7 @@
Θέμα
Σφάλμα αποκρυπτογράφησης
Όνομα συσκευής
- Αναγνωριστικό συσκευής
+ Αναγνωριστικό συσκευής
Εξαγωγή
Εισαγωγή
Επιλέξτε ένα ευρετήριο δωματίων
diff --git a/library/ui-strings/src/main/res/values-eo/strings.xml b/library/ui-strings/src/main/res/values-eo/strings.xml
index 7e1925f708..f536ca00f9 100644
--- a/library/ui-strings/src/main/res/values-eo/strings.xml
+++ b/library/ui-strings/src/main/res/values-eo/strings.xml
@@ -1084,7 +1084,7 @@
Elporti ŝlosilojn de ĉambroj
Elporti tutvoje ĉifrajn ŝlosilojn de ĉambroj
Ŝlosilo de salutaĵo
- Identigilo de salutaĵo
+ Identigilo de salutaĵo
Publika nomo
Eraris malĉifrado
Haŭto
diff --git a/library/ui-strings/src/main/res/values-es-rMX/strings.xml b/library/ui-strings/src/main/res/values-es-rMX/strings.xml
index 0b38fa6a19..c82f9aff61 100644
--- a/library/ui-strings/src/main/res/values-es-rMX/strings.xml
+++ b/library/ui-strings/src/main/res/values-es-rMX/strings.xml
@@ -249,7 +249,7 @@
Desescojer como Dirección Principal
Error en descifrar
Nombre del dispositivo
- Identificación del dispositivo
+ Identificación del dispositivo
Clave del dispositivo
Exportar claves de cifrado de extremo-a-extremo de salas
Exportar claves de salas
diff --git a/library/ui-strings/src/main/res/values-es/strings.xml b/library/ui-strings/src/main/res/values-es/strings.xml
index 4eec90fbd6..fcdd3f90a0 100644
--- a/library/ui-strings/src/main/res/values-es/strings.xml
+++ b/library/ui-strings/src/main/res/values-es/strings.xml
@@ -415,7 +415,7 @@
Dejar de Establecer como dirección principal
Error de descifrado
Nombre público
- ID de sesión
+ ID de sesión
Clave de sesión
Exportar claves de salas con cifrado Extremo-a-Extremo
Exportar claves de sala
diff --git a/library/ui-strings/src/main/res/values-et/strings.xml b/library/ui-strings/src/main/res/values-et/strings.xml
index fd2cb44ecd..d9754b5dcb 100644
--- a/library/ui-strings/src/main/res/values-et/strings.xml
+++ b/library/ui-strings/src/main/res/values-et/strings.xml
@@ -612,7 +612,7 @@
Need on alles katsejärgus olevad funktsionaalsused. Ole kasutamisel ettevaatlik.
Dekrüptimise viga
Avalik nimi
- Sessiooni tunnus
+ Sessiooni tunnus
Sessiooni võti
Ekspordi jututubade läbiva krüptimise võtmed
Ekspordi jututoa võtmed
diff --git a/library/ui-strings/src/main/res/values-eu/strings.xml b/library/ui-strings/src/main/res/values-eu/strings.xml
index 7b27d1cc1d..f1f834ee04 100644
--- a/library/ui-strings/src/main/res/values-eu/strings.xml
+++ b/library/ui-strings/src/main/res/values-eu/strings.xml
@@ -406,7 +406,7 @@ Kontuan izan ekintza honek aplikazioa berrabiaraziko duela eta denbora bat behar
Deszifratze errorea
Izen publikoa
- IDa
+ IDa
Saioaren gakoa
Esportatu E2E geletako gakoak
diff --git a/library/ui-strings/src/main/res/values-fa/strings.xml b/library/ui-strings/src/main/res/values-fa/strings.xml
index 3aa03fc77b..b7a818f58a 100644
--- a/library/ui-strings/src/main/res/values-fa/strings.xml
+++ b/library/ui-strings/src/main/res/values-fa/strings.xml
@@ -678,7 +678,7 @@
اینها ویژگیهای آزمایشیای هستند که ممکن است به روشهای نامنتظرهای حراب شوندا. با احتیاط استفاده کنید.
تنظیم به عنوان نشانی اصلی
نام عمومی
- شناسهٔ نشست
+ شناسهٔ نشست
کلید نشست
برونریزی کلیدهای اتاقهای سرتاسری
برونریزی کلیدهای اتاقها
diff --git a/library/ui-strings/src/main/res/values-fi/strings.xml b/library/ui-strings/src/main/res/values-fi/strings.xml
index fde2502ae0..a576e7f0dc 100644
--- a/library/ui-strings/src/main/res/values-fi/strings.xml
+++ b/library/ui-strings/src/main/res/values-fi/strings.xml
@@ -366,7 +366,7 @@
Kumoa pääosoitteeksi asettaminen
Salauksenpurkuvirhe
Julkinen nimi
- Istunnon tunnus
+ Istunnon tunnus
Istunnon avain
Vie salatun huoneen avaimet
Vie huoneen avaimet
diff --git a/library/ui-strings/src/main/res/values-fr-rCA/strings.xml b/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
index 29a618f415..94db2935a7 100644
--- a/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
+++ b/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
@@ -778,7 +778,7 @@
Exporter les clés des salons
Exporter les clés E2E des salons
Clé de la session
- Identifiant de session
+ Identifiant de session
Nom public
Erreur de déchiffrement
Thème
diff --git a/library/ui-strings/src/main/res/values-fr/strings.xml b/library/ui-strings/src/main/res/values-fr/strings.xml
index d73207eb3b..f560ddbb7b 100644
--- a/library/ui-strings/src/main/res/values-fr/strings.xml
+++ b/library/ui-strings/src/main/res/values-fr/strings.xml
@@ -346,7 +346,7 @@
Désactiver comme adresse principale
Erreur de déchiffrement
Nom public
- Identifiant de session
+ Identifiant de session
Clé de la session
Exporter les clés E2E des salons
Exporter les clés des salons
diff --git a/library/ui-strings/src/main/res/values-gl/strings.xml b/library/ui-strings/src/main/res/values-gl/strings.xml
index e6d26a63e5..c1e4e40a81 100644
--- a/library/ui-strings/src/main/res/values-gl/strings.xml
+++ b/library/ui-strings/src/main/res/values-gl/strings.xml
@@ -380,7 +380,7 @@
Tema
Fallo ao descifrar
Nome do dispositivo
- ID de sesión
+ ID de sesión
Chave do dispositivo
Exportar chaves E2E da sala
Exportar chaves da sala
diff --git a/library/ui-strings/src/main/res/values-hr/strings.xml b/library/ui-strings/src/main/res/values-hr/strings.xml
index dc5930b933..6d52e5cd96 100644
--- a/library/ui-strings/src/main/res/values-hr/strings.xml
+++ b/library/ui-strings/src/main/res/values-hr/strings.xml
@@ -572,7 +572,7 @@
Tema
Greška u dešifriranju
Javni naziv
- Identitet
+ Identitet
Ključ sesije
Izvezi sobne ključeve za E2E
Izvezi sobne ključeve
diff --git a/library/ui-strings/src/main/res/values-hu/strings.xml b/library/ui-strings/src/main/res/values-hu/strings.xml
index 84cae1c51d..32ecfaa45c 100644
--- a/library/ui-strings/src/main/res/values-hu/strings.xml
+++ b/library/ui-strings/src/main/res/values-hu/strings.xml
@@ -351,7 +351,7 @@
Kiszedés fő címek közül
Visszafejtés hiba
Nyilvános név
- Munkamenet-azonosító
+ Munkamenet-azonosító
Munkamenet kulcs
E2E szoba kulcsok exportálása
Szoba kulcsok exportálása
diff --git a/library/ui-strings/src/main/res/values-in/strings.xml b/library/ui-strings/src/main/res/values-in/strings.xml
index 830adf7ce9..8f910fab6b 100644
--- a/library/ui-strings/src/main/res/values-in/strings.xml
+++ b/library/ui-strings/src/main/res/values-in/strings.xml
@@ -301,7 +301,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
Tema
Kesalahan dekripsi
Nama perangkat
- ID Sesi
+ ID Sesi
Kunci perangkat
Ekspor kunci ruangan terenkripsi
Ekspor ruangan kunci
diff --git a/library/ui-strings/src/main/res/values-is/strings.xml b/library/ui-strings/src/main/res/values-is/strings.xml
index 7818761145..d25d66bfba 100644
--- a/library/ui-strings/src/main/res/values-is/strings.xml
+++ b/library/ui-strings/src/main/res/values-is/strings.xml
@@ -193,7 +193,7 @@
Þema
Afkóðunarvilla
Heiti tækis
- Auðkenni setu
+ Auðkenni setu
Dulritunarlykill setu
Flytja út
Settu inn lykilsetningu
diff --git a/library/ui-strings/src/main/res/values-it/strings.xml b/library/ui-strings/src/main/res/values-it/strings.xml
index b96693811a..01514cef90 100644
--- a/library/ui-strings/src/main/res/values-it/strings.xml
+++ b/library/ui-strings/src/main/res/values-it/strings.xml
@@ -430,7 +430,7 @@
Tema
Errore di decriptazione
Nome pubblico
- ID sessione
+ ID sessione
Chiave sessione
Esporta le chiavi di crittografia E2E delle stanze
Esporta le chiavi delle stanze
diff --git a/library/ui-strings/src/main/res/values-iw/strings.xml b/library/ui-strings/src/main/res/values-iw/strings.xml
index 6d9533852b..ff19310c8e 100644
--- a/library/ui-strings/src/main/res/values-iw/strings.xml
+++ b/library/ui-strings/src/main/res/values-iw/strings.xml
@@ -542,7 +542,7 @@
יצא מפתחות חדר
ייצא מפתחות חדר E2E
מזהה מפתח
- מזהה מושב
+ מזהה מושב
שם ציבורי
שגיאת פענוח
ערכת נושא
diff --git a/library/ui-strings/src/main/res/values-ja/strings.xml b/library/ui-strings/src/main/res/values-ja/strings.xml
index b781e4d7f0..3e817e398c 100644
--- a/library/ui-strings/src/main/res/values-ja/strings.xml
+++ b/library/ui-strings/src/main/res/values-ja/strings.xml
@@ -197,7 +197,7 @@
これらは予期しない不具合が生じるかもしれない実験的機能です。慎重に使用してください。
メインアドレスとして設定
メインアドレスとしての設定を解除
- セッションID
+ セッションID
文字の大きさ
とても小さい
小さい
diff --git a/library/ui-strings/src/main/res/values-kab/strings.xml b/library/ui-strings/src/main/res/values-kab/strings.xml
index a79b72efde..353fb99f53 100644
--- a/library/ui-strings/src/main/res/values-kab/strings.xml
+++ b/library/ui-strings/src/main/res/values-kab/strings.xml
@@ -291,7 +291,7 @@
Talqayt
Tinarimin
Asentel
- Asulay n tqimit
+ Asulay n tqimit
Tasarut n tɣimit
Sifeḍ tisura n texxamt E2E
Sifeḍ tisura n texxamt
diff --git a/library/ui-strings/src/main/res/values-ko/strings.xml b/library/ui-strings/src/main/res/values-ko/strings.xml
index ba0cbe5abd..37e8849fa8 100644
--- a/library/ui-strings/src/main/res/values-ko/strings.xml
+++ b/library/ui-strings/src/main/res/values-ko/strings.xml
@@ -431,7 +431,7 @@
테마
암호 복호화 오류
공개 이름
- ID
+ ID
기기 키
종단간 암호화 방 키 내보내기
방 키 내보내기
diff --git a/library/ui-strings/src/main/res/values-lo/strings.xml b/library/ui-strings/src/main/res/values-lo/strings.xml
index 1a9a2820b8..a92adb0225 100644
--- a/library/ui-strings/src/main/res/values-lo/strings.xml
+++ b/library/ui-strings/src/main/res/values-lo/strings.xml
@@ -909,7 +909,7 @@
ສົ່ງອອກກະແຈຫ້ອງ
ສົ່ງອອກກະແຈຫ້ອງ E2E
ລະຫັດລະບົບ
- ID ລະບົບ
+ ID ລະບົບ
ຊື່ສາທາລະນະ
ການຖອດລະຫັດຜິດພາດ
ຫົວຂໍ້
diff --git a/library/ui-strings/src/main/res/values-lv/strings.xml b/library/ui-strings/src/main/res/values-lv/strings.xml
index f1fa1502c1..1787653fae 100644
--- a/library/ui-strings/src/main/res/values-lv/strings.xml
+++ b/library/ui-strings/src/main/res/values-lv/strings.xml
@@ -469,7 +469,7 @@
Tēma
Atšifrēšanas kļūda
Ierīces nosaukums
- Sesijas ID
+ Sesijas ID
Sesijas atslēga
Eksportēt istabas šifrēšanas atslēgas
Eksportēt istabas atslēgas
diff --git a/library/ui-strings/src/main/res/values-nb-rNO/strings.xml b/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
index 031b380c7e..7af718d920 100644
--- a/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
+++ b/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
@@ -119,7 +119,7 @@
Bannlyste brukere
Avansert
Tema
- Økt-ID
+ Økt-ID
Øktnøkkel
Eksporter
Importer
diff --git a/library/ui-strings/src/main/res/values-nl/strings.xml b/library/ui-strings/src/main/res/values-nl/strings.xml
index c4cacbad93..af2aa291fc 100644
--- a/library/ui-strings/src/main/res/values-nl/strings.xml
+++ b/library/ui-strings/src/main/res/values-nl/strings.xml
@@ -275,7 +275,7 @@
Niet instellen als hoofdadres
Ontsleutelingsfout
Publieke naam
- Sessie ID
+ Sessie ID
Sessiesleutel
E2E-gesprekssleutels exporteren
Gesprekssleutels exporteren
diff --git a/library/ui-strings/src/main/res/values-nn/strings.xml b/library/ui-strings/src/main/res/values-nn/strings.xml
index a56ba0ac30..45c8679736 100644
--- a/library/ui-strings/src/main/res/values-nn/strings.xml
+++ b/library/ui-strings/src/main/res/values-nn/strings.xml
@@ -310,7 +310,7 @@
Preg
Noko gjekk gale med dekrypteringa
Offentleg namn
- Økt-ID
+ Økt-ID
Sesjonsnøkkel
Eksporter E2E-romnøkklar
Eksporter romnøkklar
diff --git a/library/ui-strings/src/main/res/values-pl/strings.xml b/library/ui-strings/src/main/res/values-pl/strings.xml
index dd10397900..e6b3a0c35c 100644
--- a/library/ui-strings/src/main/res/values-pl/strings.xml
+++ b/library/ui-strings/src/main/res/values-pl/strings.xml
@@ -231,7 +231,7 @@
Ustaw jako główny adres
Motyw
Nazwa publiczna
- ID sesji
+ ID sesji
Eksportuj
Wprowadź hasło
Potwierdź hasło
diff --git a/library/ui-strings/src/main/res/values-pt-rBR/strings.xml b/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
index 7698d1ecf9..b45de27933 100644
--- a/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
+++ b/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
@@ -418,7 +418,7 @@
Des-definir como endereço principal
Erro de decriptação
Nome público
- ID de sessão
+ ID de sessão
Chave de sessão
Exportar chaves de sala E2E
Exportar chaves de sala
diff --git a/library/ui-strings/src/main/res/values-pt/strings.xml b/library/ui-strings/src/main/res/values-pt/strings.xml
index 4daaef83b0..87b6297b2b 100644
--- a/library/ui-strings/src/main/res/values-pt/strings.xml
+++ b/library/ui-strings/src/main/res/values-pt/strings.xml
@@ -246,7 +246,7 @@ Note que esta acção irá reiniciar a aplicação e poderá levar algum tempo.<
Erro de decifragem
Nome do dispositivo
- ID do dispositivo
+ ID do dispositivo
Chave do dispositivo
Exportar chaves E2E da sala
Exportar chaves de sala
diff --git a/library/ui-strings/src/main/res/values-ru/strings.xml b/library/ui-strings/src/main/res/values-ru/strings.xml
index d21e71c7fe..f503fec55c 100644
--- a/library/ui-strings/src/main/res/values-ru/strings.xml
+++ b/library/ui-strings/src/main/res/values-ru/strings.xml
@@ -432,7 +432,7 @@
Сбросить основной адрес
Ошибка дешифровки
Публичное имя
- ID сессии
+ ID сессии
Ключ сессии
Экспорт E2E ключей комнаты
Экспорт ключей комнаты
diff --git a/library/ui-strings/src/main/res/values-sk/strings.xml b/library/ui-strings/src/main/res/values-sk/strings.xml
index 799f070eb2..3b2392a610 100644
--- a/library/ui-strings/src/main/res/values-sk/strings.xml
+++ b/library/ui-strings/src/main/res/values-sk/strings.xml
@@ -388,7 +388,7 @@
Vzhľad
Chyba dešifrovania
Verejné meno
- ID relácie
+ ID relácie
Kľúč relácie
Exportovať šifrovacie kľúče miestnosti
Exportovať kľúče miestnosti
diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml
index 8fdf4ee310..a6af0a4921 100644
--- a/library/ui-strings/src/main/res/values-sq/strings.xml
+++ b/library/ui-strings/src/main/res/values-sq/strings.xml
@@ -431,7 +431,7 @@
Temë
Gabim shfshehtëzimi
Emër publik
- ID Sesioni
+ ID Sesioni
Kyç sesioni
Eksporto kyçe dhome E2E
Eksporto kyçe dhome
diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml
index 025713272c..30b63c213c 100644
--- a/library/ui-strings/src/main/res/values-sv/strings.xml
+++ b/library/ui-strings/src/main/res/values-sv/strings.xml
@@ -918,7 +918,7 @@
Sätt upp på den här enheten
Generera en ny säkerhetskopia eller sätt en ny lösenfras för din existerande säkerhetskopia.
Detta är experimentella funktioner som kan gå sönder på oväntade sätt. Använd varsamt.
- Sessions-ID
+ Sessions-ID
Sessionsnyckel
Exportera krypteringsnycklar
Exportera rumsnycklar
diff --git a/library/ui-strings/src/main/res/values-te/strings.xml b/library/ui-strings/src/main/res/values-te/strings.xml
index 5ed2462ce8..0154d54c2e 100644
--- a/library/ui-strings/src/main/res/values-te/strings.xml
+++ b/library/ui-strings/src/main/res/values-te/strings.xml
@@ -260,7 +260,7 @@
ప్రధాన చిరునామాగా సెట్ చేయండి
పరికరం పేరు
- పరికరం ID
+ పరికరం ID
పరికరం కీ
E2E గది కీలను ఎగుమతి చేయండి
diff --git a/library/ui-strings/src/main/res/values-tr/strings.xml b/library/ui-strings/src/main/res/values-tr/strings.xml
index c097bfce6a..1f0e5be153 100644
--- a/library/ui-strings/src/main/res/values-tr/strings.xml
+++ b/library/ui-strings/src/main/res/values-tr/strings.xml
@@ -376,7 +376,7 @@
Tema
Çözme hatası
Görünür Ad
- Oturum kimliği
+ Oturum kimliği
Oturum anahtarı
E2E Oda anahtarlarını dışa aktar
Oda anahtarlarını dışa aktar
diff --git a/library/ui-strings/src/main/res/values-uk/strings.xml b/library/ui-strings/src/main/res/values-uk/strings.xml
index 6baba39a2a..1162fc2a90 100644
--- a/library/ui-strings/src/main/res/values-uk/strings.xml
+++ b/library/ui-strings/src/main/res/values-uk/strings.xml
@@ -354,7 +354,7 @@
Зробити не основною адресою
Помилка розшифрування
Загальнодоступна назва
- ID сеансу
+ ID сеансу
Ключ сеансу
Експортувати E2E ключі кімнати
Експортувати ключі кімнати
diff --git a/library/ui-strings/src/main/res/values-vi/strings.xml b/library/ui-strings/src/main/res/values-vi/strings.xml
index 2803128843..c6dc97f782 100644
--- a/library/ui-strings/src/main/res/values-vi/strings.xml
+++ b/library/ui-strings/src/main/res/values-vi/strings.xml
@@ -594,7 +594,7 @@
Hủy tài khoản
Xem lại ngay
Chìa khóa phiên
- Mã phiên
+ Mã phiên
Tên công khai
Lỗi giải mã
Những chức năng này mang tính thí nghiệm có thể còn nhiều lỗi. Lưu ý khi dùng.
diff --git a/library/ui-strings/src/main/res/values-zh-rCN/strings.xml b/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
index 16e00a0856..e05949ff7d 100644
--- a/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
+++ b/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
@@ -242,7 +242,7 @@
你的密码已更新
解密错误
公开名称
- 会话 ID
+ 会话 ID
会话密钥
导入
已验证
diff --git a/library/ui-strings/src/main/res/values-zh-rTW/strings.xml b/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
index 56d38e6e65..a2503f66f9 100644
--- a/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
+++ b/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
@@ -469,7 +469,7 @@
主題
解密錯誤
公開名稱
- 工作階段 ID
+ 工作階段 ID
工作階段金鑰
匯出聊天室的端到端加密金鑰
匯出聊天室的加密金鑰
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index c3c0fc1db0..714b48e8b4 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -1212,7 +1212,6 @@
Decryption error
Public name
- Session ID
Session key
Export E2E room keys
@@ -3263,6 +3262,7 @@
Current Session
Session
+ Device
Last activity %1$s
Filter
@@ -3290,6 +3290,12 @@
No unverified sessions found.
No inactive sessions found.
Clear Filter
+ Session details
+ Application, device, and activity information.
+ Session name
+ Session ID
+ Last activity
+ IP address
%s\nis looking a little empty.
diff --git a/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml b/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml
new file mode 100644
index 0000000000..d3884f247d
--- /dev/null
+++ b/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml b/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml
similarity index 51%
rename from library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
rename to library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml
index 97e0290815..d3b931e44a 100644
--- a/library/ui-styles/src/main/res/values/stylable_devices_list_header_view.xml
+++ b/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml
@@ -2,8 +2,8 @@
-
-
+
+
diff --git a/library/ui-styles/src/main/res/values/styles_devices_management.xml b/library/ui-styles/src/main/res/values/styles_devices_management.xml
index 6fb236d3e6..6b42b85ffd 100644
--- a/library/ui-styles/src/main/res/values/styles_devices_management.xml
+++ b/library/ui-styles/src/main/res/values/styles_devices_management.xml
@@ -1,6 +1,10 @@
+
+
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/QueryStringValue.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/QueryStringValue.kt
index d3f6ec2287..1d6e79c8f6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/QueryStringValue.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/QueryStringValue.kt
@@ -68,6 +68,11 @@ sealed interface QueryStringValue {
*/
data class Contains(override val string: String, override val case: Case = Case.SENSITIVE) : ContentQueryStringValue
+ /**
+ * The tested field must not contain the [string].
+ */
+ data class NotContains(override val string: String, override val case: Case = Case.SENSITIVE) : ContentQueryStringValue
+
/**
* Case enum for [ContentQueryStringValue].
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
index 60963ef25a..d651f06e23 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt
@@ -20,8 +20,10 @@ import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.query.RoomCategoryFilter
import org.matrix.android.sdk.api.query.RoomTagQueryFilter
import org.matrix.android.sdk.api.query.SpaceFilter
+import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams.Builder
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomType
+import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams
/**
@@ -52,6 +54,10 @@ fun spaceSummaryQueryParams(init: (RoomSummaryQueryParams.Builder.() -> Unit) =
* [roomSummaryQueryParams] and [spaceSummaryQueryParams] can also be used to build an instance of this class.
*/
data class RoomSummaryQueryParams(
+ /**
+ * Query for the roomId.
+ */
+ val roomId: QueryStringValue,
/**
* Query for the displayName of the room. The display name can be the value of the state event,
* or a value returned by [org.matrix.android.sdk.api.RoomDisplayNameFallbackProvider].
@@ -94,6 +100,7 @@ data class RoomSummaryQueryParams(
* [roomSummaryQueryParams] and [spaceSummaryQueryParams] can also be used to build an instance of [RoomSummaryQueryParams].
*/
class Builder {
+ var roomId: QueryStringValue = QueryStringValue.NotContains(RoomLocalEcho.PREFIX)
var displayName: QueryStringValue = QueryStringValue.NoCondition
var canonicalAlias: QueryStringValue = QueryStringValue.NoCondition
var memberships: List = Membership.all()
@@ -104,6 +111,7 @@ data class RoomSummaryQueryParams(
var spaceFilter: SpaceFilter = SpaceFilter.NoFilter
fun build() = RoomSummaryQueryParams(
+ roomId = roomId,
displayName = displayName,
canonicalAlias = canonicalAlias,
memberships = memberships,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/localecho/RoomLocalEcho.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/localecho/RoomLocalEcho.kt
index 7ef0d63924..ec0e642ad3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/localecho/RoomLocalEcho.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/localecho/RoomLocalEcho.kt
@@ -20,7 +20,7 @@ import java.util.UUID
object RoomLocalEcho {
- private const val PREFIX = "!local."
+ const val PREFIX = "!local."
/**
* Tell whether the provider room id is a local id.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt
index b2ab9879df..a93ff42c9e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt
@@ -38,6 +38,7 @@ internal class QueryStringValueProcessor @Inject constructor(
is ContentQueryStringValue -> when (queryStringValue) {
is QueryStringValue.Equals -> equalTo(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
is QueryStringValue.Contains -> contains(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
+ is QueryStringValue.NotContains -> not().process(field, QueryStringValue.Contains(queryStringValue.string, queryStringValue.case))
}
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt
index 82fc94df7c..afc1d5012f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt
@@ -272,6 +272,7 @@ internal class RoomSummaryDataSource @Inject constructor(
val query = with(queryStringValueProcessor) {
RoomSummaryEntity.where(realm)
.process(RoomSummaryEntityFields.ROOM_ID, QueryStringValue.IsNotEmpty)
+ .process(RoomSummaryEntityFields.ROOM_ID, queryParams.roomId)
.process(queryParams.displayName.toDisplayNameField(), queryParams.displayName)
.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
diff --git a/vector-app/build.gradle b/vector-app/build.gradle
index 235c92cfc5..82c433d2df 100644
--- a/vector-app/build.gradle
+++ b/vector-app/build.gradle
@@ -291,6 +291,12 @@ android {
}
}
+ sourceSets {
+ nightly {
+ java.srcDirs += "src/release/java"
+ }
+ }
+
flavorDimensions "store"
productFlavors {
@@ -340,16 +346,48 @@ android {
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
]
}
+
+ buildFeatures {
+ viewBinding true
+ }
}
dependencies {
implementation project(':vector')
implementation project(':vector-config')
+ debugImplementation project(':library:ui-styles')
implementation libs.dagger.hilt
implementation 'androidx.multidex:multidex:2.0.1'
implementation "androidx.sharetarget:sharetarget:1.1.0"
+ // Flipper, debug builds only
+ debugImplementation(libs.flipper.flipper) {
+ exclude group: 'com.facebook.fbjni', module: 'fbjni'
+ }
+ debugImplementation(libs.flipper.flipperNetworkPlugin) {
+ exclude group: 'com.facebook.fbjni', module: 'fbjni'
+ }
+ debugImplementation 'com.facebook.soloader:soloader:0.10.4'
+ debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.2.0"
+
+ gplayImplementation "com.google.android.gms:play-services-location:16.0.0"
+ // UnifiedPush gplay flavor only
+ gplayImplementation('com.github.UnifiedPush:android-embedded_fcm_distributor:2.1.2') {
+ exclude group: 'com.google.firebase', module: 'firebase-core'
+ exclude group: 'com.google.firebase', module: 'firebase-analytics'
+ exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
+ }
+
+ // Nightly
+ // API-only library
+ gplayImplementation libs.google.appdistributionApi
+ // Full SDK implementation
+ gplayImplementation libs.google.appdistribution
+
+ // OSS License, gplay flavor only
+ gplayImplementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
kapt libs.dagger.hiltCompiler
+ kapt libs.airbnb.epoxyProcessor
androidTestImplementation libs.androidx.testCore
androidTestImplementation libs.androidx.testRunner
@@ -374,5 +412,6 @@ dependencies {
androidTestImplementation libs.androidx.fragmentTesting
androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:1.7.10"
debugImplementation libs.androidx.fragmentTesting
+ debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
}
diff --git a/vector-app/src/debug/AndroidManifest.xml b/vector-app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000000..a7867f4081
--- /dev/null
+++ b/vector-app/src/debug/AndroidManifest.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
similarity index 99%
rename from vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
index eaaf021989..005e9c499b 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt
@@ -34,13 +34,13 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.registerForPermissionsResult
import im.vector.app.core.utils.toast
-import im.vector.app.databinding.ActivityDebugMenuBinding
import im.vector.app.features.debug.analytics.DebugAnalyticsActivity
import im.vector.app.features.debug.features.DebugFeaturesSettingsActivity
import im.vector.app.features.debug.leak.DebugMemoryLeaksActivity
import im.vector.app.features.debug.sas.DebugSasEmojiActivity
import im.vector.app.features.debug.settings.DebugPrivateSettingsActivity
import im.vector.app.features.qrcode.QrCodeScannerActivity
+import im.vector.application.databinding.ActivityDebugMenuBinding
import im.vector.lib.ui.styles.debug.DebugMaterialThemeDarkDefaultActivity
import im.vector.lib.ui.styles.debug.DebugMaterialThemeDarkTestActivity
import im.vector.lib.ui.styles.debug.DebugMaterialThemeDarkVectorActivity
diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
similarity index 97%
rename from vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
index 0f00f2daa5..a9be5512e4 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt
@@ -23,13 +23,13 @@ import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import dagger.hilt.android.AndroidEntryPoint
-import im.vector.app.R
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.onPermissionDeniedDialog
import im.vector.app.core.utils.onPermissionDeniedSnackbar
import im.vector.app.core.utils.registerForPermissionsResult
-import im.vector.app.databinding.ActivityDebugPermissionBinding
+import im.vector.application.R
+import im.vector.application.databinding.ActivityDebugPermissionBinding
import timber.log.Timber
@AndroidEntryPoint
diff --git a/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt
similarity index 97%
rename from vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt
index 59c60e0e15..6e94bce00a 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt
@@ -20,9 +20,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
-import im.vector.app.R
-import im.vector.app.databinding.ActivityTestLinkifyBinding
-import im.vector.app.databinding.ItemTestLinkifyBinding
+import im.vector.application.R
+import im.vector.application.databinding.ActivityTestLinkifyBinding
+import im.vector.application.databinding.ItemTestLinkifyBinding
class TestLinkifyActivity : AppCompatActivity() {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsActivity.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt
similarity index 97%
rename from vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt
index eb23fe6383..0fa11d7220 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsFragment.kt
@@ -25,7 +25,7 @@ import com.airbnb.mvrx.withState
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.extensions.toOnOff
import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentDebugAnalyticsBinding
+import im.vector.application.databinding.FragmentDebugAnalyticsBinding
import me.gujun.android.span.span
class DebugAnalyticsFragment : VectorBaseFragment() {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewActions.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewModel.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt b/vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/analytics/DebugAnalyticsViewState.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt b/vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/di/DebugModule.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/FeaturesModule.kt b/vector-app/src/debug/java/im/vector/app/features/debug/di/FeaturesModule.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/di/FeaturesModule.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/di/FeaturesModule.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt b/vector-app/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt
similarity index 94%
rename from vector/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt
index 1e9b88c048..38765bfa9b 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/BooleanFeatureItem.kt
@@ -23,9 +23,9 @@ import android.widget.Spinner
import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
-import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
+import im.vector.application.R
@EpoxyModelClass
abstract class BooleanFeatureItem : VectorEpoxyModel(R.layout.item_feature) {
@@ -70,8 +70,8 @@ abstract class BooleanFeatureItem : VectorEpoxyModel(
}
class Holder : VectorEpoxyHolder() {
- val label by bind(im.vector.app.R.id.feature_label)
- val optionsSpinner by bind(im.vector.app.R.id.feature_options)
+ val label by bind(R.id.feature_label)
+ val optionsSpinner by bind(R.id.feature_options)
}
interface Listener {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesSettingsActivity.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt
similarity index 92%
rename from vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt
index 5e16182f3c..57138b9a47 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/DebugVectorOverrides.kt
@@ -66,13 +66,13 @@ class DebugVectorOverrides(private val context: Context) : VectorOverrides {
suspend fun setHomeserverCapabilities(block: HomeserverCapabilitiesOverride.() -> HomeserverCapabilitiesOverride) {
val capabilitiesOverride = block(forceHomeserverCapabilities.firstOrNull() ?: HomeserverCapabilitiesOverride(null, null))
context.dataStore.edit { settings ->
- when (capabilitiesOverride.canChangeDisplayName) {
+ when (val canChangeDisplayName = capabilitiesOverride.canChangeDisplayName) {
null -> settings.remove(forceCanChangeDisplayName)
- else -> settings[forceCanChangeDisplayName] = capabilitiesOverride.canChangeDisplayName
+ else -> settings[forceCanChangeDisplayName] = canChangeDisplayName
}
- when (capabilitiesOverride.canChangeAvatar) {
+ when (val canChangeAvatar = capabilitiesOverride.canChangeAvatar) {
null -> settings.remove(forceCanChangeAvatar)
- else -> settings[forceCanChangeAvatar] = capabilitiesOverride.canChangeAvatar
+ else -> settings[forceCanChangeAvatar] = canChangeAvatar
}
}
}
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt
similarity index 94%
rename from vector/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt
index 5231e591da..00f74515cc 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/features/EnumFeatureItem.kt
@@ -23,9 +23,9 @@ import android.widget.Spinner
import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
-import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
+import im.vector.application.R
@EpoxyModelClass
abstract class EnumFeatureItem : VectorEpoxyModel(R.layout.item_feature) {
@@ -70,8 +70,8 @@ abstract class EnumFeatureItem : VectorEpoxyModel(R.layo
}
class Holder : VectorEpoxyHolder() {
- val label by bind(im.vector.app.R.id.feature_label)
- val optionsSpinner by bind(im.vector.app.R.id.feature_options)
+ val label by bind(R.id.feature_label)
+ val optionsSpinner by bind(R.id.feature_options)
}
interface Listener {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/FeaturesController.kt b/vector-app/src/debug/java/im/vector/app/features/debug/features/FeaturesController.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/features/FeaturesController.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/features/FeaturesController.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
similarity index 96%
rename from vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
index 2abf6487e2..e9afa9aea9 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt
@@ -25,7 +25,7 @@ import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentDebugMemoryLeaksBinding
+import im.vector.application.databinding.FragmentDebugMemoryLeaksBinding
@AndroidEntryPoint
class DebugMemoryLeaksFragment :
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
similarity index 98%
rename from vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
index 5432cb0888..26eb1c1025 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 New Vector Ltd
+ * 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.
diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt b/vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiController.kt b/vector-app/src/debug/java/im/vector/app/features/debug/sas/SasEmojiController.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiController.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/sas/SasEmojiController.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt b/vector-app/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt
similarity index 98%
rename from vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt
index 179ee35693..bbc438e4b2 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/sas/SasEmojiItem.kt
@@ -21,9 +21,9 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
-import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
+import im.vector.application.R
import me.gujun.android.span.image
import me.gujun.android.span.span
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsActivity.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt
similarity index 97%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt
index be3d41e0e1..020c228521 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsFragment.kt
@@ -25,8 +25,8 @@ import android.view.ViewGroup
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.app.core.platform.VectorBaseFragment
-import im.vector.app.databinding.FragmentDebugPrivateSettingsBinding
import im.vector.app.features.home.room.list.home.release.ReleaseNotesActivity
+import im.vector.application.databinding.FragmentDebugPrivateSettingsBinding
class DebugPrivateSettingsFragment : VectorBaseFragment() {
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewActions.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewActions.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewActions.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewActions.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewModel.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewState.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewState.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewState.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/DebugPrivateSettingsViewState.kt
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt
similarity index 97%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt
index 7f510ee5e9..2800b7bd8d 100644
--- a/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt
+++ b/vector-app/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt
@@ -24,7 +24,7 @@ import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.LinearLayout
-import im.vector.app.databinding.ViewBooleanDropdownBinding
+import im.vector.application.databinding.ViewBooleanDropdownBinding
class OverrideDropdownView @JvmOverloads constructor(
context: Context,
diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/PrivateSettingOverrides.kt b/vector-app/src/debug/java/im/vector/app/features/debug/settings/PrivateSettingOverrides.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/features/debug/settings/PrivateSettingOverrides.kt
rename to vector-app/src/debug/java/im/vector/app/features/debug/settings/PrivateSettingOverrides.kt
diff --git a/vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt b/vector-app/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
rename to vector-app/src/debug/java/im/vector/app/flipper/VectorFlipperProxy.kt
diff --git a/vector/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt b/vector-app/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt
rename to vector-app/src/debug/java/im/vector/app/leakcanary/LeakCanaryLeakDetector.kt
diff --git a/vector/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt b/vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
similarity index 100%
rename from vector/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
rename to vector-app/src/debug/java/im/vector/app/receivers/VectorDebugReceiver.kt
diff --git a/vector/src/debug/res/layout/activity_debug_menu.xml b/vector-app/src/debug/res/layout/activity_debug_menu.xml
similarity index 100%
rename from vector/src/debug/res/layout/activity_debug_menu.xml
rename to vector-app/src/debug/res/layout/activity_debug_menu.xml
diff --git a/vector/src/debug/res/layout/activity_debug_permission.xml b/vector-app/src/debug/res/layout/activity_debug_permission.xml
similarity index 100%
rename from vector/src/debug/res/layout/activity_debug_permission.xml
rename to vector-app/src/debug/res/layout/activity_debug_permission.xml
diff --git a/vector/src/debug/res/layout/activity_test_linkify.xml b/vector-app/src/debug/res/layout/activity_test_linkify.xml
similarity index 100%
rename from vector/src/debug/res/layout/activity_test_linkify.xml
rename to vector-app/src/debug/res/layout/activity_test_linkify.xml
diff --git a/vector/src/debug/res/layout/demo_theme_sample.xml b/vector-app/src/debug/res/layout/demo_theme_sample.xml
similarity index 100%
rename from vector/src/debug/res/layout/demo_theme_sample.xml
rename to vector-app/src/debug/res/layout/demo_theme_sample.xml
diff --git a/vector/src/debug/res/layout/demo_themes.xml b/vector-app/src/debug/res/layout/demo_themes.xml
similarity index 100%
rename from vector/src/debug/res/layout/demo_themes.xml
rename to vector-app/src/debug/res/layout/demo_themes.xml
diff --git a/vector/src/debug/res/layout/fragment_debug_analytics.xml b/vector-app/src/debug/res/layout/fragment_debug_analytics.xml
similarity index 100%
rename from vector/src/debug/res/layout/fragment_debug_analytics.xml
rename to vector-app/src/debug/res/layout/fragment_debug_analytics.xml
diff --git a/vector/src/debug/res/layout/fragment_debug_memory_leaks.xml b/vector-app/src/debug/res/layout/fragment_debug_memory_leaks.xml
similarity index 100%
rename from vector/src/debug/res/layout/fragment_debug_memory_leaks.xml
rename to vector-app/src/debug/res/layout/fragment_debug_memory_leaks.xml
diff --git a/vector/src/debug/res/layout/fragment_debug_private_settings.xml b/vector-app/src/debug/res/layout/fragment_debug_private_settings.xml
similarity index 100%
rename from vector/src/debug/res/layout/fragment_debug_private_settings.xml
rename to vector-app/src/debug/res/layout/fragment_debug_private_settings.xml
diff --git a/vector/src/debug/res/layout/item_feature.xml b/vector-app/src/debug/res/layout/item_feature.xml
similarity index 100%
rename from vector/src/debug/res/layout/item_feature.xml
rename to vector-app/src/debug/res/layout/item_feature.xml
diff --git a/vector/src/debug/res/layout/item_sas_emoji.xml b/vector-app/src/debug/res/layout/item_sas_emoji.xml
similarity index 100%
rename from vector/src/debug/res/layout/item_sas_emoji.xml
rename to vector-app/src/debug/res/layout/item_sas_emoji.xml
diff --git a/vector/src/debug/res/layout/item_test_linkify.xml b/vector-app/src/debug/res/layout/item_test_linkify.xml
similarity index 100%
rename from vector/src/debug/res/layout/item_test_linkify.xml
rename to vector-app/src/debug/res/layout/item_test_linkify.xml
diff --git a/vector/src/debug/res/layout/view_boolean_dropdown.xml b/vector-app/src/debug/res/layout/view_boolean_dropdown.xml
similarity index 100%
rename from vector/src/debug/res/layout/view_boolean_dropdown.xml
rename to vector-app/src/debug/res/layout/view_boolean_dropdown.xml
diff --git a/vector/src/debug/res/values/strings.xml b/vector-app/src/debug/res/values/strings.xml
similarity index 100%
rename from vector/src/debug/res/values/strings.xml
rename to vector-app/src/debug/res/values/strings.xml
diff --git a/vector/src/debug/res/xml/shortcuts.xml b/vector-app/src/debug/res/xml/shortcuts.xml
similarity index 100%
rename from vector/src/debug/res/xml/shortcuts.xml
rename to vector-app/src/debug/res/xml/shortcuts.xml
diff --git a/vector/src/fdroid/AndroidManifest.xml b/vector-app/src/fdroid/AndroidManifest.xml
similarity index 78%
rename from vector/src/fdroid/AndroidManifest.xml
rename to vector-app/src/fdroid/AndroidManifest.xml
index 15db89ca13..354d450958 100644
--- a/vector/src/fdroid/AndroidManifest.xml
+++ b/vector-app/src/fdroid/AndroidManifest.xml
@@ -1,7 +1,6 @@
+ xmlns:tools="http://schemas.android.com/tools">
@@ -15,7 +14,7 @@
@@ -24,12 +23,12 @@
diff --git a/vector/src/fdroid/java/im/vector/app/di/FlavorModule.kt b/vector-app/src/fdroid/java/im/vector/app/di/FlavorModule.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/di/FlavorModule.kt
rename to vector-app/src/fdroid/java/im/vector/app/di/FlavorModule.kt
diff --git a/vector/src/fdroid/java/im/vector/app/di/NotificationTestModule.kt b/vector-app/src/fdroid/java/im/vector/app/di/NotificationTestModule.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/di/NotificationTestModule.kt
rename to vector-app/src/fdroid/java/im/vector/app/di/NotificationTestModule.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/BackgroundSyncStarter.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestAutoStartBoot.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/package-info.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/package-info.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/package-info.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/package-info.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt
similarity index 95%
rename from vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt
index bd1e0eb0ee..bccbf42e92 100644
--- a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt
+++ b/vector-app/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt
@@ -16,6 +16,7 @@
package im.vector.app.fdroid.receiver
+import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
@@ -65,6 +66,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
companion object {
private const val REQUEST_CODE = 0
+ @SuppressLint("WrongConstant") // PendingIntentCompat.FLAG_IMMUTABLE is a false positive
fun scheduleAlarm(context: Context, sessionId: String, delayInSeconds: Int, clock: Clock) {
// Reschedule
Timber.v("## Sync: Scheduling alarm for background sync in $delayInSeconds seconds")
@@ -87,6 +89,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
}
}
+ @SuppressLint("WrongConstant") // PendingIntentCompat.FLAG_IMMUTABLE is a false positive
fun cancelAlarm(context: Context) {
Timber.v("## Sync: Cancel alarm for background sync")
val intent = Intent(context, AlarmSyncBroadcastReceiver::class.java)
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/service/FDroidGuardServiceStarter.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/service/FDroidGuardServiceStarter.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/service/FDroidGuardServiceStarter.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/service/FDroidGuardServiceStarter.kt
diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/service/GuardAndroidService.kt b/vector-app/src/fdroid/java/im/vector/app/fdroid/service/GuardAndroidService.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/fdroid/service/GuardAndroidService.kt
rename to vector-app/src/fdroid/java/im/vector/app/fdroid/service/GuardAndroidService.kt
diff --git a/vector/src/fdroid/java/im/vector/app/push/fcm/FdroidFcmHelper.kt b/vector-app/src/fdroid/java/im/vector/app/push/fcm/FdroidFcmHelper.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/push/fcm/FdroidFcmHelper.kt
rename to vector-app/src/fdroid/java/im/vector/app/push/fcm/FdroidFcmHelper.kt
diff --git a/vector/src/fdroid/java/im/vector/app/push/fcm/FdroidNotificationTroubleshootTestManagerFactory.kt b/vector-app/src/fdroid/java/im/vector/app/push/fcm/FdroidNotificationTroubleshootTestManagerFactory.kt
similarity index 100%
rename from vector/src/fdroid/java/im/vector/app/push/fcm/FdroidNotificationTroubleshootTestManagerFactory.kt
rename to vector-app/src/fdroid/java/im/vector/app/push/fcm/FdroidNotificationTroubleshootTestManagerFactory.kt
diff --git a/vector/src/gplay/java/im/vector/app/GoogleFlavorLegals.kt b/vector-app/src/gplay/java/im/vector/app/GoogleFlavorLegals.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/GoogleFlavorLegals.kt
rename to vector-app/src/gplay/java/im/vector/app/GoogleFlavorLegals.kt
diff --git a/vector/src/gplay/java/im/vector/app/di/FlavorModule.kt b/vector-app/src/gplay/java/im/vector/app/di/FlavorModule.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/di/FlavorModule.kt
rename to vector-app/src/gplay/java/im/vector/app/di/FlavorModule.kt
diff --git a/vector/src/gplay/java/im/vector/app/di/NotificationTestModule.kt b/vector-app/src/gplay/java/im/vector/app/di/NotificationTestModule.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/di/NotificationTestModule.kt
rename to vector-app/src/gplay/java/im/vector/app/di/NotificationTestModule.kt
diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt b/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt
rename to vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt
diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt b/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt
rename to vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt
diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt
rename to vector-app/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt
diff --git a/vector/src/gplay/java/im/vector/app/gplay/package-info.kt b/vector-app/src/gplay/java/im/vector/app/gplay/package-info.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/gplay/package-info.kt
rename to vector-app/src/gplay/java/im/vector/app/gplay/package-info.kt
diff --git a/vector/src/gplay/java/im/vector/app/nightly/FirebaseNightlyProxy.kt b/vector-app/src/gplay/java/im/vector/app/nightly/FirebaseNightlyProxy.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/nightly/FirebaseNightlyProxy.kt
rename to vector-app/src/gplay/java/im/vector/app/nightly/FirebaseNightlyProxy.kt
diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt b/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt
rename to vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleFcmHelper.kt
diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/GoogleNotificationTroubleshootTestManagerFactory.kt b/vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleNotificationTroubleshootTestManagerFactory.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/push/fcm/GoogleNotificationTroubleshootTestManagerFactory.kt
rename to vector-app/src/gplay/java/im/vector/app/push/fcm/GoogleNotificationTroubleshootTestManagerFactory.kt
diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt b/vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt
similarity index 100%
rename from vector/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt
rename to vector-app/src/gplay/java/im/vector/app/push/fcm/VectorFirebaseMessagingService.kt
diff --git a/vector-app/src/main/AndroidManifest.xml b/vector-app/src/main/AndroidManifest.xml
index 84607cf3d7..bff594c0de 100644
--- a/vector-app/src/main/AndroidManifest.xml
+++ b/vector-app/src/main/AndroidManifest.xml
@@ -18,6 +18,24 @@
tools:ignore="UnusedAttribute"
tools:replace="android:allowBackup">
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/nightly/res/xml/shortcuts.xml b/vector-app/src/nightly/res/xml/shortcuts.xml
similarity index 100%
rename from vector/src/nightly/res/xml/shortcuts.xml
rename to vector-app/src/nightly/res/xml/shortcuts.xml
diff --git a/vector/src/release/java/im/vector/app/core/di/DebugModule.kt b/vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt
similarity index 100%
rename from vector/src/release/java/im/vector/app/core/di/DebugModule.kt
rename to vector-app/src/release/java/im/vector/app/core/di/DebugModule.kt
diff --git a/vector/src/release/java/im/vector/app/core/di/FeaturesModule.kt b/vector-app/src/release/java/im/vector/app/core/di/FeaturesModule.kt
similarity index 100%
rename from vector/src/release/java/im/vector/app/core/di/FeaturesModule.kt
rename to vector-app/src/release/java/im/vector/app/core/di/FeaturesModule.kt
diff --git a/vector/src/release/java/im/vector/app/receivers/DebugReceiver.kt b/vector-app/src/release/java/im/vector/app/receivers/DebugReceiver.kt
similarity index 100%
rename from vector/src/release/java/im/vector/app/receivers/DebugReceiver.kt
rename to vector-app/src/release/java/im/vector/app/receivers/DebugReceiver.kt
diff --git a/vector/src/release/res/xml/shortcuts.xml b/vector-app/src/release/res/xml/shortcuts.xml
similarity index 100%
rename from vector/src/release/res/xml/shortcuts.xml
rename to vector-app/src/release/res/xml/shortcuts.xml
diff --git a/vector/build.gradle b/vector/build.gradle
index a5538053fc..f6db2a61df 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -66,23 +66,6 @@ android {
testCoverageEnabled = coverage.enableTestCoverage
}
}
- nightly {
- initWith release
- matchingFallbacks = ['release']
- }
- release
- }
-
- flavorDimensions "store"
-
- productFlavors {
- gplay {
- dimension "store"
- }
-
- fdroid {
- dimension "store"
- }
}
compileOptions {
@@ -111,10 +94,6 @@ android {
test {
java.srcDirs += "src/sharedTest/java"
}
- // Add sourceSets for `release` version when building `nightly`
- nightly {
- java.srcDirs += "src/release/java"
- }
}
buildFeatures {
@@ -183,12 +162,6 @@ dependencies {
// Snap Helper https://github.com/rubensousa/GravitySnapHelper
api 'com.github.rubensousa:gravitysnaphelper:2.2.2'
- // Nightly
- // API-only library
- gplayImplementation libs.google.appdistributionApi
- // Full SDK implementation
- gplayImplementation libs.google.appdistribution
-
// Work
api libs.androidx.work
@@ -204,7 +177,7 @@ dependencies {
// UI
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation libs.google.material
- implementation 'me.gujun.android:span:1.7'
+ api 'me.gujun.android:span:1.7'
implementation libs.markwon.core
implementation libs.markwon.extLatex
implementation libs.markwon.inlineParser
@@ -256,15 +229,6 @@ dependencies {
// UnifiedPush
implementation 'com.github.UnifiedPush:android-connector:2.0.1'
- // UnifiedPush gplay flavor only
- gplayImplementation('com.google.firebase:firebase-messaging:23.0.8') {
- exclude group: 'com.google.firebase', module: 'firebase-core'
- exclude group: 'com.google.firebase', module: 'firebase-analytics'
- exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
- }
-
- // OSS License, gplay flavor only
- gplayImplementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'
implementation "androidx.emoji2:emoji2:1.1.0"
@@ -300,14 +264,12 @@ dependencies {
implementation 'commons-codec:commons-codec:1.15'
// MapTiler
- fdroidApi(libs.maplibre.androidSdk) {
+ api(libs.maplibre.androidSdk) {
exclude group: 'com.google.android.gms', module: 'play-services-location'
}
- fdroidApi(libs.maplibre.pluginAnnotation) {
+ api(libs.maplibre.pluginAnnotation) {
exclude group: 'com.google.android.gms', module: 'play-services-location'
}
- gplayApi libs.maplibre.androidSdk
- gplayApi libs.maplibre.pluginAnnotation
// TESTS
testImplementation libs.tests.junit
@@ -320,19 +282,6 @@ dependencies {
exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
}
- // Flipper, debug builds only
- debugImplementation(libs.flipper.flipper) {
- exclude group: 'com.facebook.fbjni', module: 'fbjni'
- }
- debugImplementation(libs.flipper.flipperNetworkPlugin) {
- exclude group: 'com.facebook.fbjni', module: 'fbjni'
- }
- debugImplementation 'com.facebook.soloader:soloader:0.10.4'
- debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.2.0"
-
- // Activate when you want to check for leaks, from time to time.
- debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
-
androidTestImplementation libs.androidx.testCore
androidTestImplementation libs.androidx.testRunner
androidTestImplementation libs.androidx.testRules
diff --git a/vector/src/androidTest/AndroidManifest.xml b/vector/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000000..5c3b99d4d1
--- /dev/null
+++ b/vector/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml
deleted file mode 100644
index 94fdb1b389..0000000000
--- a/vector/src/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index 30b5fc2de9..ecc721524d 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -90,23 +90,6 @@
android:name=".features.MainActivity"
android:theme="@style/Theme.Vector.Launcher" />
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index 21016077a1..10aee61ae5 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -89,6 +89,7 @@ import im.vector.app.features.settings.crosssigning.CrossSigningSettingsViewMode
import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheetViewModel
import im.vector.app.features.settings.devices.DevicesViewModel
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsViewModel
+import im.vector.app.features.settings.devices.v2.details.SessionDetailsViewModel
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewViewModel
import im.vector.app.features.settings.devtools.AccountDataViewModel
import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel
@@ -647,4 +648,9 @@ interface MavericksViewModelModule {
@IntoMap
@MavericksViewModelKey(OtherSessionsViewModel::class)
fun otherSessionsViewModelFactory(factory: OtherSessionsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+ @Binds
+ @IntoMap
+ @MavericksViewModelKey(SessionDetailsViewModel::class)
+ fun sessionDetailsViewModelFactory(factory: SessionDetailsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
}
diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt
index ddc281fdd1..ec6f3288f8 100644
--- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt
+++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt
@@ -25,6 +25,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.CallSuper
+import androidx.annotation.FloatRange
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
@@ -39,6 +40,7 @@ import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.plan.MobileScreen
+import io.github.hyuwah.draggableviewlib.Utils
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks
@@ -165,6 +167,13 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe
forceExpandState()
}
+ protected fun setPeekHeightAsScreenPercentage(@FloatRange(from = 0.0, to = 1.0) percentage: Float) {
+ context?.let {
+ val screenHeight = Utils.getScreenHeight(it)
+ bottomSheetBehavior?.setPeekHeight((screenHeight * percentage).toInt(), true)
+ }
+ }
+
protected fun forceExpandState() {
if (showExpanded) {
// Force the bottom sheet to be expanded
diff --git a/vector/src/main/java/im/vector/app/core/utils/CopyToClipboardUseCase.kt b/vector/src/main/java/im/vector/app/core/utils/CopyToClipboardUseCase.kt
new file mode 100644
index 0000000000..19ad9e2bba
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/core/utils/CopyToClipboardUseCase.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.core.utils
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import androidx.core.content.getSystemService
+import dagger.hilt.android.qualifiers.ApplicationContext
+import javax.inject.Inject
+
+class CopyToClipboardUseCase @Inject constructor(
+ @ApplicationContext private val context: Context,
+) {
+
+ fun execute(text: CharSequence) {
+ context.getSystemService()
+ ?.setPrimaryClip(ClipData.newPlainText("", text))
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt
index 6cfe8acc16..cde4fe2a35 100644
--- a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt
+++ b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt
@@ -19,8 +19,6 @@ package im.vector.app.core.utils
import android.annotation.TargetApi
import android.app.Activity
import android.content.ActivityNotFoundException
-import android.content.ClipData
-import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -100,8 +98,7 @@ fun requestDisablingBatteryOptimization(activity: Activity, activityResultLaunch
* @param toastMessage content of the toast message as a String resource
*/
fun copyToClipboard(context: Context, text: CharSequence, showToast: Boolean = true, @StringRes toastMessage: Int = R.string.copied_to_clipboard) {
- val clipboard = context.getSystemService()!!
- clipboard.setPrimaryClip(ClipData.newPlainText("", text))
+ CopyToClipboardUseCase(context).execute(text)
if (showToast) {
context.toast(toastMessage)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
index 3681ba4c15..f31f8a7d92 100644
--- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
@@ -201,13 +201,12 @@ class NewHomeDetailFragment :
private fun setupFabs() {
showFABs()
- views.newLayoutCreateChatButton.setOnClickListener {
- newChatBottomSheet.show(requireActivity().supportFragmentManager, NewChatBottomSheet.TAG)
+ views.newLayoutCreateChatButton.debouncedClicks {
+ newChatBottomSheet.takeIf { !it.isAdded }?.show(requireActivity().supportFragmentManager, NewChatBottomSheet.TAG)
}
- views.newLayoutOpenSpacesButton.setOnClickListener {
- // Click action for open spaces modal goes here
- spaceListBottomSheet.show(requireActivity().supportFragmentManager, SpaceListBottomSheet.TAG)
+ views.newLayoutOpenSpacesButton.debouncedClicks {
+ spaceListBottomSheet.takeIf { !it.isAdded }?.show(requireActivity().supportFragmentManager, SpaceListBottomSheet.TAG)
}
}
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 ca64a0f991..8283447a4d 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
@@ -47,7 +47,6 @@ import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.getRoomSummary
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
-import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
@@ -127,20 +126,13 @@ class RoomListViewModel @AssistedInject constructor(
}
private fun observeLocalRooms() {
- val queryParams = roomSummaryQueryParams {
- memberships = listOf(Membership.JOIN)
- }
session
.flow()
- .liveRoomSummaries(queryParams)
- .map { roomSummaries ->
- roomSummaries.mapNotNull { summary ->
- summary.roomId.takeIf { RoomLocalEcho.isLocalEchoId(it) }
- }.toSet()
- }
- .setOnEach { roomIds ->
- copy(localRoomIds = roomIds)
- }
+ .liveRoomSummaries(roomSummaryQueryParams {
+ roomId = QueryStringValue.Contains(RoomLocalEcho.PREFIX)
+ })
+ .map { page -> page.map { it.roomId } }
+ .setOnEach { copy(localRoomIds = it) }
}
companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory()
@@ -181,7 +173,7 @@ class RoomListViewModel @AssistedInject constructor(
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
}
- fun deleteLocalRooms(roomsIds: Set) {
+ fun deleteLocalRooms(roomsIds: Iterable) {
viewModelScope.launch {
roomsIds.forEach {
session.roomService().deleteLocalRoom(it)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt
index 3f46293346..5f62cba948 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewState.kt
@@ -31,7 +31,7 @@ data class RoomListViewState(
val asyncSuggestedRooms: Async> = Uninitialized,
val currentUserName: String? = null,
val asyncSelectedSpace: Async = Uninitialized,
- val localRoomIds: Set = emptySet()
+ val localRoomIds: List = emptyList()
) : MavericksState {
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListFragment.kt
index a4738a550c..4ae2c7d514 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/HomeRoomListFragment.kt
@@ -123,7 +123,6 @@ class HomeRoomListFragment :
roomListViewModel.handle(HomeRoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY))
}
is RoomListQuickActionsSharedAction.Leave -> {
- roomListViewModel.handle(HomeRoomListAction.LeaveRoom(quickAction.roomId))
promptLeaveRoom(quickAction.roomId)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/NewChatBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/NewChatBottomSheet.kt
index 05b86f7393..0cba387a36 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/home/NewChatBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/NewChatBottomSheet.kt
@@ -16,43 +16,50 @@
package im.vector.app.features.home.room.list.home
+import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.FragmentNewChatBottomSheetBinding
import im.vector.app.features.navigation.Navigator
import javax.inject.Inject
@AndroidEntryPoint
-class NewChatBottomSheet @Inject constructor() : BottomSheetDialogFragment() {
+class NewChatBottomSheet : VectorBaseBottomSheetDialogFragment() {
@Inject lateinit var navigator: Navigator
- private lateinit var binding: FragmentNewChatBottomSheetBinding
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentNewChatBottomSheetBinding {
+ return FragmentNewChatBottomSheetBinding.inflate(inflater, container, false)
+ }
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
- binding = FragmentNewChatBottomSheetBinding.inflate(inflater, container, false)
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
initFABs()
- return binding.root
}
private fun initFABs() {
- binding.startChat.setOnClickListener {
+ views.startChat.debouncedClicks {
navigator.openCreateDirectRoom(requireActivity())
}
- binding.createRoom.setOnClickListener {
+ views.createRoom.debouncedClicks {
navigator.openCreateRoom(requireActivity())
}
- binding.exploreRooms.setOnClickListener {
+ views.exploreRooms.debouncedClicks {
navigator.openRoomDirectory(requireContext())
}
}
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return super.onCreateDialog(savedInstanceState).apply {
+ setPeekHeightAsScreenPercentage(0.5f)
+ }
+ }
+
companion object {
const val TAG = "NewChatBottomSheet"
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt
index 8be9bf12f9..f7c9eccd0b 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/header/HomeRoomsHeadersController.kt
@@ -18,6 +18,7 @@ package im.vector.app.features.home.room.list.home.header
import android.content.res.Resources
import android.util.TypedValue
+import androidx.recyclerview.widget.RecyclerView
import com.airbnb.epoxy.Carousel
import com.airbnb.epoxy.CarouselModelBuilder
import com.airbnb.epoxy.EpoxyController
@@ -44,6 +45,25 @@ class HomeRoomsHeadersController @Inject constructor(
var recentsRoomListener: RoomListListener? = null
var invitesClickListener: (() -> Unit)? = null
+ private var carousel: Carousel? = null
+
+ private val carouselAdapterObserver = object : RecyclerView.AdapterDataObserver() {
+ override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
+ if (toPosition == 0 || fromPosition == 0) {
+ carousel?.post {
+ carousel?.layoutManager?.scrollToPosition(0)
+ }
+ }
+ super.onItemRangeMoved(fromPosition, toPosition, itemCount)
+ }
+
+ override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
+ if (positionStart == 0) {
+ carousel?.layoutManager?.scrollToPosition(0)
+ }
+ }
+ }
+
private val recentsHPadding = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
4f,
@@ -92,9 +112,28 @@ class HomeRoomsHeadersController @Inject constructor(
)
)
onBind { _, view, _ ->
+ host.carousel = view
+
val colorSurface = MaterialColors.getColor(view, R.attr.vctr_toolbar_background)
view.setBackgroundColor(colorSurface)
+
+ try {
+ view.adapter?.registerAdapterDataObserver(host.carouselAdapterObserver)
+ } catch (e: IllegalStateException) {
+ // do nothing
+ }
}
+
+ onUnbind { _, view ->
+ host.carousel = null
+
+ try {
+ view.adapter?.unregisterAdapterDataObserver(host.carouselAdapterObserver)
+ } catch (e: IllegalStateException) {
+ // do nothing
+ }
+ }
+
withModelsFrom(recents) { roomSummary ->
val onClick = host.recentsRoomListener?.let { it::onRoomClicked }
val onLongClick = host.recentsRoomListener?.let { it::onRoomLongClicked }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCase.kt
new file mode 100644
index 0000000000..25b5ddb0e8
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCase.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import org.matrix.android.sdk.api.extensions.orFalse
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import javax.inject.Inject
+
+class CheckIfSectionDeviceIsVisibleUseCase @Inject constructor() {
+
+ fun execute(deviceInfo: DeviceInfo): Boolean {
+ return deviceInfo.lastSeenIp?.isNotEmpty().orFalse()
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCase.kt
new file mode 100644
index 0000000000..4998b4b5d3
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCase.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import org.matrix.android.sdk.api.extensions.orFalse
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import javax.inject.Inject
+
+class CheckIfSectionSessionIsVisibleUseCase @Inject constructor() {
+
+ fun execute(deviceInfo: DeviceInfo): Boolean {
+ return deviceInfo.displayName?.isNotEmpty().orFalse() ||
+ deviceInfo.deviceId?.isNotEmpty().orFalse() ||
+ (deviceInfo.lastSeenTs ?: 0) > 0
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt
new file mode 100644
index 0000000000..0fa524dab4
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsAction.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import im.vector.app.core.platform.VectorViewModelAction
+
+sealed class SessionDetailsAction : VectorViewModelAction {
+ data class CopyToClipboard(val content: String) : SessionDetailsAction()
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt
new file mode 100644
index 0000000000..101bf1da2e
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsActivity.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.airbnb.mvrx.Mavericks
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.extensions.addFragment
+import im.vector.app.core.platform.SimpleFragmentActivity
+
+/**
+ * Display the details info about a Session.
+ */
+@AndroidEntryPoint
+class SessionDetailsActivity : SimpleFragmentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ if (isFirstCreation()) {
+ addFragment(
+ container = views.container,
+ fragmentClass = SessionDetailsFragment::class.java,
+ params = intent.getParcelableExtra(Mavericks.KEY_ARG)
+ )
+ }
+ }
+
+ companion object {
+ fun newIntent(context: Context, deviceId: String): Intent {
+ return Intent(context, SessionDetailsActivity::class.java).apply {
+ putExtra(Mavericks.KEY_ARG, SessionDetailsArgs(deviceId))
+ }
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt
new file mode 100644
index 0000000000..97716d7c47
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsArgs.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class SessionDetailsArgs(
+ val deviceId: String
+) : Parcelable
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsContentItem.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsContentItem.kt
new file mode 100644
index 0000000000..665ba5126c
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsContentItem.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.view.View
+import android.widget.TextView
+import androidx.core.view.isVisible
+import com.airbnb.epoxy.EpoxyAttribute
+import com.airbnb.epoxy.EpoxyModelClass
+import im.vector.app.R
+import im.vector.app.core.epoxy.VectorEpoxyHolder
+import im.vector.app.core.epoxy.VectorEpoxyModel
+
+@EpoxyModelClass
+abstract class SessionDetailsContentItem : VectorEpoxyModel(R.layout.item_session_details_content) {
+
+ @EpoxyAttribute
+ var title: String? = null
+
+ @EpoxyAttribute
+ var description: String? = null
+
+ @EpoxyAttribute
+ var hasDivider: Boolean = true
+
+ @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
+ var onLongClickListener: View.OnLongClickListener? = null
+
+ override fun bind(holder: Holder) {
+ super.bind(holder)
+ holder.sessionDetailsContentTitle.text = title
+ holder.sessionDetailsContentDescription.text = description
+ holder.view.isClickable = onLongClickListener != null
+ holder.view.setOnLongClickListener(onLongClickListener)
+ holder.sessionDetailsContentDivider.isVisible = hasDivider
+ }
+
+ class Holder : VectorEpoxyHolder() {
+ val sessionDetailsContentTitle by bind(R.id.sessionDetailsContentTitle)
+ val sessionDetailsContentDescription by bind(R.id.sessionDetailsContentDescription)
+ val sessionDetailsContentDivider by bind(R.id.sessionDetailsContentDivider)
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt
new file mode 100644
index 0000000000..1fb5be4d78
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsController.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.view.View
+import androidx.annotation.StringRes
+import com.airbnb.epoxy.TypedEpoxyController
+import im.vector.app.R
+import im.vector.app.core.date.DateFormatKind
+import im.vector.app.core.date.VectorDateFormatter
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.core.utils.DimensionConverter
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import javax.inject.Inject
+
+class SessionDetailsController @Inject constructor(
+ private val checkIfSectionSessionIsVisibleUseCase: CheckIfSectionSessionIsVisibleUseCase,
+ private val checkIfSectionDeviceIsVisibleUseCase: CheckIfSectionDeviceIsVisibleUseCase,
+ private val stringProvider: StringProvider,
+ private val dateFormatter: VectorDateFormatter,
+ private val dimensionConverter: DimensionConverter,
+) : TypedEpoxyController() {
+
+ var callback: Callback? = null
+
+ interface Callback {
+ fun onItemLongClicked(content: String)
+ }
+
+ override fun buildModels(data: DeviceInfo?) {
+ data?.let { info ->
+ val hasSectionSession = hasSectionSession(data)
+ if (hasSectionSession) {
+ buildSectionSession(info)
+ }
+
+ if (hasSectionDevice(data)) {
+ buildSectionDevice(info, addExtraTopMargin = hasSectionSession)
+ }
+ }
+ }
+
+ private fun buildHeaderItem(@StringRes titleResId: Int, addExtraTopMargin: Boolean = false) {
+ val host = this
+ sessionDetailsHeaderItem {
+ id(titleResId)
+ title(host.stringProvider.getString(titleResId))
+ addExtraTopMargin(addExtraTopMargin)
+ dimensionConverter(host.dimensionConverter)
+ }
+ }
+
+ private fun buildContentItem(@StringRes titleResId: Int, value: String, hasDivider: Boolean) {
+ val host = this
+ sessionDetailsContentItem {
+ id(titleResId)
+ title(host.stringProvider.getString(titleResId))
+ description(value)
+ hasDivider(hasDivider)
+ onLongClickListener(View.OnLongClickListener {
+ host.callback?.onItemLongClicked(value)
+ true
+ })
+ }
+ }
+
+ private fun hasSectionSession(data: DeviceInfo): Boolean {
+ return checkIfSectionSessionIsVisibleUseCase.execute(data)
+ }
+
+ private fun buildSectionSession(data: DeviceInfo) {
+ val sessionName = data.displayName
+ val sessionId = data.deviceId
+ val sessionLastSeenTs = data.lastSeenTs
+
+ buildHeaderItem(R.string.device_manager_session_title)
+
+ sessionName?.let {
+ val hasDivider = sessionId != null || sessionLastSeenTs != null
+ buildContentItem(R.string.device_manager_session_details_session_name, it, hasDivider)
+ }
+ sessionId?.let {
+ val hasDivider = sessionLastSeenTs != null
+ buildContentItem(R.string.device_manager_session_details_session_id, it, hasDivider)
+ }
+ sessionLastSeenTs?.let {
+ val formattedDate = dateFormatter.format(it, DateFormatKind.MESSAGE_DETAIL)
+ val hasDivider = false
+ buildContentItem(R.string.device_manager_session_details_session_last_activity, formattedDate, hasDivider)
+ }
+ }
+
+ private fun hasSectionDevice(data: DeviceInfo): Boolean {
+ return checkIfSectionDeviceIsVisibleUseCase.execute(data)
+ }
+
+ private fun buildSectionDevice(data: DeviceInfo, addExtraTopMargin: Boolean) {
+ val lastSeenIp = data.lastSeenIp
+
+ buildHeaderItem(R.string.device_manager_device_title, addExtraTopMargin)
+
+ lastSeenIp?.let {
+ val hasDivider = false
+ buildContentItem(R.string.device_manager_session_details_device_ip_address, it, hasDivider)
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt
new file mode 100644
index 0000000000..5d7717e5f7
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsFragment.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.R
+import im.vector.app.core.extensions.cleanup
+import im.vector.app.core.extensions.configureWith
+import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.platform.showOptimizedSnackbar
+import im.vector.app.databinding.FragmentSessionDetailsBinding
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+import javax.inject.Inject
+
+/**
+ * Display the details info about a Session.
+ */
+@AndroidEntryPoint
+class SessionDetailsFragment :
+ VectorBaseFragment() {
+
+ @Inject lateinit var sessionDetailsController: SessionDetailsController
+
+ private val viewModel: SessionDetailsViewModel by fragmentViewModel()
+
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSessionDetailsBinding {
+ return FragmentSessionDetailsBinding.inflate(inflater, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ initToolbar()
+ initSessionDetails()
+ observeViewEvents()
+ }
+
+ private fun initToolbar() {
+ (activity as? AppCompatActivity)
+ ?.supportActionBar
+ ?.setTitle(R.string.device_manager_session_details_title)
+ }
+
+ private fun initSessionDetails() {
+ sessionDetailsController.callback = object : SessionDetailsController.Callback {
+ override fun onItemLongClicked(content: String) {
+ viewModel.handle(SessionDetailsAction.CopyToClipboard(content))
+ }
+ }
+ views.sessionDetails.configureWith(sessionDetailsController)
+ }
+
+ private fun observeViewEvents() {
+ viewModel.observeViewEvents { viewEvent ->
+ when (viewEvent) {
+ SessionDetailsViewEvent.ContentCopiedToClipboard -> view?.showOptimizedSnackbar(getString(R.string.copied_to_clipboard))
+ }
+ }
+ }
+
+ override fun onDestroyView() {
+ cleanUpSessionDetails()
+ super.onDestroyView()
+ }
+
+ private fun cleanUpSessionDetails() {
+ sessionDetailsController.callback = null
+ views.sessionDetails.cleanup()
+ }
+
+ override fun invalidate() = withState(viewModel) { state ->
+ if (state.deviceInfo is Success) {
+ renderSessionDetails(state.deviceInfo.invoke())
+ } else {
+ hideSessionDetails()
+ }
+ }
+
+ private fun renderSessionDetails(deviceInfo: DeviceInfo) {
+ views.sessionDetails.isVisible = true
+ sessionDetailsController.setData(deviceInfo)
+ }
+
+ private fun hideSessionDetails() {
+ views.sessionDetails.isGone = true
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsHeaderItem.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsHeaderItem.kt
new file mode 100644
index 0000000000..ff6ce3faad
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsHeaderItem.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.core.view.updateLayoutParams
+import androidx.core.view.updateMargins
+import com.airbnb.epoxy.EpoxyAttribute
+import com.airbnb.epoxy.EpoxyModelClass
+import im.vector.app.R
+import im.vector.app.core.epoxy.VectorEpoxyHolder
+import im.vector.app.core.epoxy.VectorEpoxyModel
+import im.vector.app.core.utils.DimensionConverter
+
+private const val EXTRA_TOP_MARGIN_DP = 48
+
+@EpoxyModelClass
+abstract class SessionDetailsHeaderItem : VectorEpoxyModel(R.layout.item_session_details_header) {
+
+ @EpoxyAttribute
+ var title: String? = null
+
+ @EpoxyAttribute
+ var addExtraTopMargin: Boolean = false
+
+ @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
+ var dimensionConverter: DimensionConverter? = null
+
+ override fun bind(holder: Holder) {
+ super.bind(holder)
+ holder.sessionDetailsHeaderTitle.text = title
+ val topMargin = if (addExtraTopMargin) {
+ dimensionConverter?.dpToPx(EXTRA_TOP_MARGIN_DP) ?: 0
+ } else {
+ 0
+ }
+ holder.sessionDetailsHeaderTitle.updateLayoutParams {
+ updateMargins(top = topMargin)
+ }
+ }
+
+ class Holder : VectorEpoxyHolder() {
+ val sessionDetailsHeaderTitle by bind(R.id.sessionDetailsHeaderTitle)
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewEvent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewEvent.kt
new file mode 100644
index 0000000000..02b313319e
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewEvent.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import im.vector.app.core.platform.VectorViewEvents
+
+sealed class SessionDetailsViewEvent : VectorViewEvents {
+ object ContentCopiedToClipboard : SessionDetailsViewEvent()
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt
new file mode 100644
index 0000000000..c37858cc54
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModel.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import com.airbnb.mvrx.MavericksViewModelFactory
+import com.airbnb.mvrx.Success
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
+import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.core.utils.CopyToClipboardUseCase
+import im.vector.app.features.settings.devices.v2.overview.GetDeviceFullInfoUseCase
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+
+class SessionDetailsViewModel @AssistedInject constructor(
+ @Assisted val initialState: SessionDetailsViewState,
+ private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase,
+ private val copyToClipboardUseCase: CopyToClipboardUseCase,
+) : VectorViewModel(initialState) {
+
+ companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory()
+
+ @AssistedFactory
+ interface Factory : MavericksAssistedViewModelFactory {
+ override fun create(initialState: SessionDetailsViewState): SessionDetailsViewModel
+ }
+
+ init {
+ observeSessionInfo(initialState.deviceId)
+ }
+
+ private fun observeSessionInfo(deviceId: String) {
+ getDeviceFullInfoUseCase.execute(deviceId)
+ .onEach { setState { copy(deviceInfo = Success(it.deviceInfo)) } }
+ .launchIn(viewModelScope)
+ }
+
+ override fun handle(action: SessionDetailsAction) {
+ return when (action) {
+ is SessionDetailsAction.CopyToClipboard -> handleCopyToClipboard(action)
+ }
+ }
+
+ private fun handleCopyToClipboard(copyToClipboard: SessionDetailsAction.CopyToClipboard) {
+ copyToClipboardUseCase.execute(copyToClipboard.content)
+ _viewEvents.post(SessionDetailsViewEvent.ContentCopiedToClipboard)
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt
new file mode 100644
index 0000000000..15868d3110
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewState.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.MavericksState
+import com.airbnb.mvrx.Uninitialized
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+
+data class SessionDetailsViewState(
+ val deviceId: String,
+ val deviceInfo: Async = Uninitialized,
+) : MavericksState {
+ constructor(args: SessionDetailsArgs) : this(
+ deviceId = args.deviceId
+ )
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
index 0cb621a502..555d216dfc 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
@@ -24,6 +24,7 @@ import androidx.core.view.isVisible
import im.vector.app.R
import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter
+import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.extensions.setTextWithColoredPart
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.DrawableProvider
@@ -91,13 +92,14 @@ class SessionInfoView @JvmOverloads constructor(
private fun appendLearnMoreToVerificationStatus() {
val status = views.sessionInfoVerificationStatusDetailTextView.text
val learnMore = context.getString(R.string.action_learn_more)
- val stringBuilder = StringBuilder()
- stringBuilder.append(status)
- stringBuilder.append(" ")
- stringBuilder.append(learnMore)
+ val statusText = buildString {
+ append(status)
+ append(" ")
+ append(learnMore)
+ }
views.sessionInfoVerificationStatusDetailTextView.setTextWithColoredPart(
- fullText = stringBuilder.toString(),
+ fullText = statusText,
coloredPart = learnMore,
underline = false
) {
@@ -172,15 +174,7 @@ class SessionInfoView @JvmOverloads constructor(
views.sessionInfoLastActivityTextView.isGone = true
}
- deviceInfo.lastSeenIp
- ?.takeIf { isLastSeenDetailsVisible }
- ?.let { ipAddress ->
- views.sessionInfoLastIPAddressTextView.isVisible = true
- views.sessionInfoLastIPAddressTextView.text = ipAddress
- }
- ?: run {
- views.sessionInfoLastIPAddressTextView.isGone = true
- }
+ views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible })
}
private fun renderDetailsButton(isDetailsButtonVisible: Boolean) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
index 924228444a..ef8682df01 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt
@@ -54,26 +54,27 @@ class SessionsListHeaderView @JvmOverloads constructor(
}
private fun setTitle(typedArray: TypedArray) {
- val title = typedArray.getString(R.styleable.SessionsListHeaderView_devicesListHeaderTitle)
+ val title = typedArray.getString(R.styleable.SessionsListHeaderView_sessionsListHeaderTitle)
binding.sessionsListHeaderTitle.setTextOrHide(title)
}
private fun setDescription(typedArray: TypedArray) {
- val description = typedArray.getString(R.styleable.SessionsListHeaderView_devicesListHeaderDescription)
+ val description = typedArray.getString(R.styleable.SessionsListHeaderView_sessionsListHeaderDescription)
if (description.isNullOrEmpty()) {
binding.sessionsListHeaderDescription.isVisible = false
return
}
val learnMore = context.getString(R.string.action_learn_more)
- val stringBuilder = StringBuilder()
- stringBuilder.append(description)
- stringBuilder.append(" ")
- stringBuilder.append(learnMore)
+ val fullDescription = buildString {
+ append(description)
+ append(" ")
+ append(learnMore)
+ }
binding.sessionsListHeaderDescription.isVisible = true
binding.sessionsListHeaderDescription.setTextWithColoredPart(
- fullText = stringBuilder.toString(),
+ fullText = fullDescription,
coloredPart = learnMore,
underline = false
) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt
index fff81b6dc5..5a8106f2fd 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt
@@ -25,8 +25,8 @@ import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveU
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
-import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
+import org.matrix.android.sdk.flow.unwrap
import javax.inject.Inject
class GetDeviceFullInfoUseCase @Inject constructor(
@@ -36,7 +36,7 @@ class GetDeviceFullInfoUseCase @Inject constructor(
private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase,
) {
- fun execute(deviceId: String): Flow> {
+ fun execute(deviceId: String): Flow {
return activeSessionHolder.getSafeActiveSession()?.let { session ->
combine(
getCurrentSessionCrossSigningInfoUseCase.execute(),
@@ -58,7 +58,7 @@ class GetDeviceFullInfoUseCase @Inject constructor(
null
}
fullInfo.toOptional()
- }
+ }.unwrap()
} ?: emptyFlow()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntryView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntryView.kt
new file mode 100644
index 0000000000..5c4f0047ce
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntryView.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.res.use
+import im.vector.app.R
+import im.vector.app.core.extensions.setAttributeBackground
+import im.vector.app.databinding.ViewSessionOverviewEntryBinding
+
+class SessionOverviewEntryView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ private val binding = ViewSessionOverviewEntryBinding.inflate(
+ LayoutInflater.from(context),
+ this
+ )
+
+ init {
+ initBackground()
+ context.obtainStyledAttributes(
+ attrs,
+ R.styleable.SessionOverviewEntryView,
+ 0,
+ 0
+ ).use {
+ setTitle(it)
+ setDescription(it)
+ }
+ }
+
+ private fun initBackground() {
+ binding.root.setAttributeBackground(android.R.attr.selectableItemBackground)
+ }
+
+ private fun setTitle(typedArray: TypedArray) {
+ val title = typedArray.getString(R.styleable.SessionOverviewEntryView_sessionOverviewEntryTitle)
+ binding.sessionsOverviewEntryTitle.text = title
+ }
+
+ private fun setDescription(typedArray: TypedArray) {
+ val description = typedArray.getString(R.styleable.SessionOverviewEntryView_sessionOverviewEntryDescription)
+ binding.sessionsOverviewEntryDescription.text = description
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
index c5cd80bd3c..3fea7a9316 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
@@ -45,6 +45,8 @@ import javax.inject.Inject
class SessionOverviewFragment :
VectorBaseFragment() {
+ @Inject lateinit var viewNavigator: SessionOverviewViewNavigator
+
@Inject lateinit var dateFormatter: VectorDateFormatter
@Inject lateinit var drawableProvider: DrawableProvider
@@ -79,6 +81,7 @@ class SessionOverviewFragment :
override fun invalidate() = withState(viewModel) { state ->
updateToolbar(state.isCurrentSession)
+ updateEntryDetails(state.deviceId)
if (state.deviceInfo is Success) {
renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke())
} else {
@@ -93,6 +96,12 @@ class SessionOverviewFragment :
?.setTitle(titleResId)
}
+ private fun updateEntryDetails(deviceId: String) {
+ views.sessionOverviewEntryDetails.setOnClickListener {
+ viewNavigator.navigateToSessionDetails(requireContext(), deviceId)
+ }
+ }
+
private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) {
views.sessionOverviewInfo.isVisible = true
val viewState = SessionInfoViewState(
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
index 1a1d3640a2..bdcdc40c56 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt
@@ -26,7 +26,6 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.session.Session
@@ -54,7 +53,6 @@ class SessionOverviewViewModel @AssistedInject constructor(
private fun observeSessionInfo(deviceId: String) {
getDeviceFullInfoUseCase.execute(deviceId)
- .mapNotNull { it.getOrNull() }
.onEach { setState { copy(deviceInfo = Success(it)) } }
.launchIn(viewModelScope)
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigator.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigator.kt
new file mode 100644
index 0000000000..ef61856255
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigator.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.content.Context
+import im.vector.app.features.settings.devices.v2.details.SessionDetailsActivity
+import javax.inject.Inject
+
+class SessionOverviewViewNavigator @Inject constructor() {
+
+ fun navigateToSessionDetails(context: Context, deviceId: String) {
+ context.startActivity(SessionDetailsActivity.newIntent(context, deviceId))
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListBottomSheet.kt
index 910f8c5379..4787aed8ae 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListBottomSheet.kt
@@ -16,25 +16,32 @@
package im.vector.app.features.spaces
+import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import im.vector.app.R
import im.vector.app.core.extensions.replaceChildFragment
+import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.FragmentSpacesBottomSheetBinding
-class SpaceListBottomSheet : BottomSheetDialogFragment() {
+class SpaceListBottomSheet : VectorBaseBottomSheetDialogFragment() {
- private lateinit var binding: FragmentSpacesBottomSheetBinding
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSpacesBottomSheetBinding {
+ return FragmentSpacesBottomSheetBinding.inflate(inflater, container, false)
+ }
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
- binding = FragmentSpacesBottomSheetBinding.inflate(inflater, container, false)
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
replaceChildFragment(R.id.space_list, SpaceListFragment::class.java)
}
- return binding.root
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return super.onCreateDialog(savedInstanceState).apply {
+ setPeekHeightAsScreenPercentage(0.75f)
+ }
}
companion object {
diff --git a/vector/src/main/res/layout/dialog_device_verify.xml b/vector/src/main/res/layout/dialog_device_verify.xml
index bbf346c8dc..475ffc69af 100644
--- a/vector/src/main/res/layout/dialog_device_verify.xml
+++ b/vector/src/main/res/layout/dialog_device_verify.xml
@@ -39,7 +39,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
- android:text="@string/encryption_information_device_id"
+ android:text="@string/device_manager_session_details_session_id"
android:textStyle="bold" />
-
\ No newline at end of file
+
diff --git a/vector/src/main/res/layout/fragment_other_sessions.xml b/vector/src/main/res/layout/fragment_other_sessions.xml
index fe532b887d..037f85ad28 100644
--- a/vector/src/main/res/layout/fragment_other_sessions.xml
+++ b/vector/src/main/res/layout/fragment_other_sessions.xml
@@ -53,8 +53,8 @@
android:id="@+id/deviceListHeaderOtherSessions"
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:devicesListHeaderDescription="@string/device_manager_sessions_other_description"
- app:devicesListHeaderTitle=""
+ app:sessionsListHeaderDescription="@string/device_manager_sessions_other_description"
+ app:sessionsListHeaderTitle=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appBarLayout" />
diff --git a/vector/src/main/res/layout/fragment_session_details.xml b/vector/src/main/res/layout/fragment_session_details.xml
new file mode 100644
index 0000000000..de0ce27798
--- /dev/null
+++ b/vector/src/main/res/layout/fragment_session_details.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/fragment_session_overview.xml b/vector/src/main/res/layout/fragment_session_overview.xml
index 156e61673b..f4573ef85e 100644
--- a/vector/src/main/res/layout/fragment_session_overview.xml
+++ b/vector/src/main/res/layout/fragment_session_overview.xml
@@ -1,20 +1,36 @@
-
-
+
-
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/fragment_settings_devices.xml b/vector/src/main/res/layout/fragment_settings_devices.xml
index c367506819..8e2daa2239 100644
--- a/vector/src/main/res/layout/fragment_settings_devices.xml
+++ b/vector/src/main/res/layout/fragment_settings_devices.xml
@@ -12,8 +12,8 @@
android:id="@+id/deviceListHeaderSectionSecurityRecommendations"
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:devicesListHeaderDescription="@string/device_manager_header_section_security_recommendations_description"
- app:devicesListHeaderTitle="@string/device_manager_header_section_security_recommendations_title"
+ app:sessionsListHeaderDescription="@string/device_manager_header_section_security_recommendations_description"
+ app:sessionsListHeaderTitle="@string/device_manager_header_section_security_recommendations_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -60,8 +60,8 @@
android:id="@+id/deviceListHeaderCurrentSession"
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:devicesListHeaderDescription=""
- app:devicesListHeaderTitle="@string/device_manager_current_session_title"
+ app:sessionsListHeaderDescription=""
+ app:sessionsListHeaderTitle="@string/device_manager_current_session_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/deviceListSecurityRecommendationsDivider" />
@@ -90,8 +90,8 @@
android:id="@+id/deviceListHeaderOtherSessions"
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:devicesListHeaderDescription="@string/device_manager_sessions_other_description"
- app:devicesListHeaderTitle="@string/device_manager_sessions_other_title"
+ app:sessionsListHeaderDescription="@string/device_manager_sessions_other_description"
+ app:sessionsListHeaderTitle="@string/device_manager_sessions_other_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/deviceListDividerCurrentSession" />
diff --git a/vector/src/main/res/layout/item_session_details_content.xml b/vector/src/main/res/layout/item_session_details_content.xml
new file mode 100644
index 0000000000..fefae65b3d
--- /dev/null
+++ b/vector/src/main/res/layout/item_session_details_content.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/item_session_details_header.xml b/vector/src/main/res/layout/item_session_details_header.xml
new file mode 100644
index 0000000000..571a541b2b
--- /dev/null
+++ b/vector/src/main/res/layout/item_session_details_header.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/view_session_overview_entry.xml b/vector/src/main/res/layout/view_session_overview_entry.xml
new file mode 100644
index 0000000000..464f775192
--- /dev/null
+++ b/vector/src/main/res/layout/view_session_overview_entry.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml
index c246a40f71..1e8997e9c8 100644
--- a/vector/src/main/res/xml/vector_settings_security_privacy.xml
+++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml
@@ -35,7 +35,7 @@
()
+ every { ClipData.newPlainText(any(), any()) } returns clipData
+
+ // When
+ copyToClipboardUseCase.execute(A_TEXT)
+
+ // Then
+ clipboardManager.verifySetPrimaryClip(clipData)
+ verify { ClipData.newPlainText("", A_TEXT) }
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCaseTest.kt
new file mode 100644
index 0000000000..b618c58b7e
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionDeviceIsVisibleUseCaseTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import io.mockk.every
+import io.mockk.mockk
+import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+
+private const val AN_IP_ADDRESS = "ip-address"
+
+class CheckIfSectionDeviceIsVisibleUseCaseTest {
+
+ private val checkIfSectionDeviceIsVisibleUseCase = CheckIfSectionDeviceIsVisibleUseCase()
+
+ @Test
+ fun `given device info with Ip address when checking is device section is visible then it returns true`() = runTest {
+ // Given
+ val deviceInfo = givenADeviceInfo(AN_IP_ADDRESS)
+
+ // When
+ val result = checkIfSectionDeviceIsVisibleUseCase.execute(deviceInfo)
+
+ // Then
+ result shouldBeEqualTo true
+ }
+
+ @Test
+ fun `given device info with empty or null Ip address when checking is device section is visible then it returns false`() = runTest {
+ // Given
+ val deviceInfo1 = givenADeviceInfo("")
+ val deviceInfo2 = givenADeviceInfo(null)
+
+ // When
+ val result1 = checkIfSectionDeviceIsVisibleUseCase.execute(deviceInfo1)
+ val result2 = checkIfSectionDeviceIsVisibleUseCase.execute(deviceInfo2)
+
+ // Then
+ result1 shouldBeEqualTo false
+ result2 shouldBeEqualTo false
+ }
+
+ private fun givenADeviceInfo(ipAddress: String?): DeviceInfo {
+ val info = mockk()
+ every { info.lastSeenIp } returns ipAddress
+ return info
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCaseTest.kt
new file mode 100644
index 0000000000..806c86d175
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/CheckIfSectionSessionIsVisibleUseCaseTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import io.mockk.every
+import io.mockk.mockk
+import kotlinx.coroutines.test.runTest
+import org.amshove.kluent.shouldBeEqualTo
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+
+private const val A_SESSION_NAME = "session-name"
+private const val A_SESSION_ID = "session-id"
+private const val A_LAST_SEEN_TS = 123L
+
+class CheckIfSectionSessionIsVisibleUseCaseTest {
+
+ private val checkIfSectionSessionIsVisibleUseCase = CheckIfSectionSessionIsVisibleUseCase()
+
+ @Test
+ fun `given device info with name, id or lastSeenTs when checking is session section is visible then it returns true`() = runTest {
+ // Given
+ val deviceInfoList = listOf(
+ givenADeviceInfo(
+ sessionName = A_SESSION_NAME,
+ sessionId = null,
+ lastSeenTs = null,
+ ),
+ givenADeviceInfo(
+ sessionName = null,
+ sessionId = A_SESSION_ID,
+ lastSeenTs = null,
+ ),
+ givenADeviceInfo(
+ sessionName = null,
+ sessionId = null,
+ lastSeenTs = A_LAST_SEEN_TS,
+ ),
+ givenADeviceInfo(
+ sessionName = A_SESSION_NAME,
+ sessionId = A_SESSION_ID,
+ lastSeenTs = null,
+ ),
+ givenADeviceInfo(
+ sessionName = A_SESSION_NAME,
+ sessionId = null,
+ lastSeenTs = A_LAST_SEEN_TS,
+ ),
+ givenADeviceInfo(
+ sessionName = null,
+ sessionId = A_SESSION_ID,
+ lastSeenTs = A_LAST_SEEN_TS,
+ ),
+ givenADeviceInfo(
+ sessionName = A_SESSION_NAME,
+ sessionId = A_SESSION_ID,
+ lastSeenTs = A_LAST_SEEN_TS,
+ ),
+ )
+
+ deviceInfoList.forEach { deviceInfo ->
+ // When
+ val result = checkIfSectionSessionIsVisibleUseCase.execute(deviceInfo)
+
+ // Then
+ result shouldBeEqualTo true
+ }
+ }
+
+ @Test
+ fun `given device info with missing session info when checking is session section is visible then it returns true`() = runTest {
+ // Given
+ val deviceInfoList = listOf(
+ givenADeviceInfo(
+ sessionName = null,
+ sessionId = null,
+ lastSeenTs = null,
+ ),
+ givenADeviceInfo(
+ sessionName = "",
+ sessionId = "",
+ lastSeenTs = null,
+ ),
+ givenADeviceInfo(
+ sessionName = "",
+ sessionId = "",
+ lastSeenTs = -1,
+ ),
+ )
+
+ deviceInfoList.forEach { deviceInfo ->
+ // When
+ val result = checkIfSectionSessionIsVisibleUseCase.execute(deviceInfo)
+
+ // Then
+ result shouldBeEqualTo false
+ }
+ }
+
+ private fun givenADeviceInfo(
+ sessionName: String?,
+ sessionId: String?,
+ lastSeenTs: Long?,
+ ): DeviceInfo {
+ val info = mockk()
+ every { info.displayName } returns sessionName
+ every { info.deviceId } returns sessionId
+ every { info.lastSeenTs } returns lastSeenTs
+ return info
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt
new file mode 100644
index 0000000000..df0613e06b
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/SessionDetailsViewModelTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.details
+
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.test.MvRxTestRule
+import im.vector.app.core.utils.CopyToClipboardUseCase
+import im.vector.app.features.settings.devices.v2.DeviceFullInfo
+import im.vector.app.features.settings.devices.v2.overview.GetDeviceFullInfoUseCase
+import im.vector.app.test.test
+import im.vector.app.test.testDispatcher
+import io.mockk.every
+import io.mockk.just
+import io.mockk.mockk
+import io.mockk.runs
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+import org.junit.Rule
+import org.junit.Test
+import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
+
+private const val A_SESSION_ID = "session-id"
+private const val A_TEXT = "text"
+
+class SessionDetailsViewModelTest {
+
+ @get:Rule
+ val mvRxTestRule = MvRxTestRule(testDispatcher = testDispatcher)
+
+ private val args = SessionDetailsArgs(
+ deviceId = A_SESSION_ID
+ )
+ private val getDeviceFullInfoUseCase = mockk()
+ private val copyToClipboardUseCase = mockk()
+
+ private fun createViewModel() = SessionDetailsViewModel(
+ initialState = SessionDetailsViewState(args),
+ getDeviceFullInfoUseCase = getDeviceFullInfoUseCase,
+ copyToClipboardUseCase = copyToClipboardUseCase,
+ )
+
+ @Test
+ fun `given the viewModel has been initialized then viewState is updated with session info`() {
+ // Given
+ val deviceFullInfo = mockk()
+ val deviceInfo = mockk()
+ every { deviceFullInfo.deviceInfo } returns deviceInfo
+ every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo)
+ val expectedState = SessionDetailsViewState(
+ deviceId = A_SESSION_ID,
+ deviceInfo = Success(deviceInfo)
+ )
+
+ // When
+ val viewModel = createViewModel()
+
+ // Then
+ viewModel.test()
+ .assertLatestState { state -> state == expectedState }
+ .finish()
+ verify { getDeviceFullInfoUseCase.execute(A_SESSION_ID) }
+ }
+
+ @Test
+ fun `given copyToClipboard action when viewModel handle it then related use case is executed and viewEvent is updated`() {
+ // Given
+ val deviceFullInfo = mockk()
+ val deviceInfo = mockk()
+ every { deviceFullInfo.deviceInfo } returns deviceInfo
+ every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo)
+ val action = SessionDetailsAction.CopyToClipboard(A_TEXT)
+ every { copyToClipboardUseCase.execute(any()) } just runs
+
+ // When
+ val viewModel = createViewModel()
+ val viewModelTest = viewModel.test()
+ viewModel.handle(action)
+
+ // Then
+ viewModelTest
+ .assertEvent { it is SessionDetailsViewEvent.ContentCopiedToClipboard }
+ .finish()
+ verify { copyToClipboardUseCase.execute(A_TEXT) }
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt
index 7dc8e08a4e..9c7515f2da 100644
--- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt
@@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
+import org.amshove.kluent.shouldBeNull
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -72,6 +73,7 @@ class GetDeviceFullInfoUseCaseTest {
@Test
fun `given current session and info for device when getting device info then the result is correct`() = runTest {
+ // Given
val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo()
val deviceInfo = DeviceInfo(
lastSeenTs = A_TIMESTAMP
@@ -85,15 +87,15 @@ class GetDeviceFullInfoUseCaseTest {
val isInactive = false
every { checkIfSessionIsInactiveUseCase.execute(any()) } returns isInactive
+ // When
val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
- deviceFullInfo shouldBeEqualTo Optional(
- DeviceFullInfo(
- deviceInfo = deviceInfo,
- cryptoDeviceInfo = cryptoDeviceInfo,
- roomEncryptionTrustLevel = trustLevel,
- isInactive = isInactive,
- )
+ // Then
+ deviceFullInfo shouldBeEqualTo DeviceFullInfo(
+ deviceInfo = deviceInfo,
+ cryptoDeviceInfo = cryptoDeviceInfo,
+ roomEncryptionTrustLevel = trustLevel,
+ isInactive = isInactive,
)
verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
verify { getCurrentSessionCrossSigningInfoUseCase.execute() }
@@ -104,16 +106,19 @@ class GetDeviceFullInfoUseCaseTest {
}
@Test
- fun `given current session and no info for device when getting device info then the result is null`() = runTest {
+ fun `given current session and no info for device when getting device info then the result is empty`() = runTest {
+ // Given
givenCurrentSessionCrossSigningInfo()
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(null))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow()
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(null))
fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow()
+ // When
val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
- deviceFullInfo shouldBeEqualTo Optional(null)
+ // Then
+ deviceFullInfo.shouldBeNull()
verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() }
verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() }
@@ -121,11 +126,14 @@ class GetDeviceFullInfoUseCaseTest {
@Test
fun `given no current session when getting device info then the result is empty`() = runTest {
+ // Given
fakeActiveSessionHolder.givenGetSafeActiveSessionReturns(null)
+ // When
val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull()
- deviceFullInfo shouldBeEqualTo null
+ // Then
+ deviceFullInfo.shouldBeNull()
verify { fakeActiveSessionHolder.instance.getSafeActiveSession() }
}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
index 4a26fc4adc..8d4e49ef85 100644
--- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt
@@ -21,22 +21,21 @@ import com.airbnb.mvrx.test.MvRxTestRule
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.test.fakes.FakeSession
import im.vector.app.test.test
+import im.vector.app.test.testDispatcher
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
import org.junit.Rule
import org.junit.Test
import org.matrix.android.sdk.api.auth.data.SessionParams
-import org.matrix.android.sdk.api.util.Optional
private const val A_SESSION_ID = "session-id"
class SessionOverviewViewModelTest {
@get:Rule
- val mvRxTestRule = MvRxTestRule(testDispatcher = UnconfinedTestDispatcher())
+ val mvRxTestRule = MvRxTestRule(testDispatcher = testDispatcher)
private val args = SessionOverviewArgs(
deviceId = A_SESSION_ID
@@ -52,17 +51,20 @@ class SessionOverviewViewModelTest {
@Test
fun `given the viewModel has been initialized then viewState is updated with session info`() {
+ // Given
val sessionParams = givenIdForSession(A_SESSION_ID)
val deviceFullInfo = mockk()
- every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(Optional(deviceFullInfo))
+ every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo)
val expectedState = SessionOverviewViewState(
deviceId = A_SESSION_ID,
isCurrentSession = true,
deviceInfo = Success(deviceFullInfo)
)
+ // When
val viewModel = createViewModel()
+ // Then
viewModel.test()
.assertLatestState { state -> state == expectedState }
.finish()
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigatorTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigatorTest.kt
new file mode 100644
index 0000000000..56f1e5920d
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewNavigatorTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.devices.v2.overview
+
+import android.content.Intent
+import im.vector.app.features.settings.devices.v2.details.SessionDetailsActivity
+import im.vector.app.test.fakes.FakeContext
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.mockkObject
+import io.mockk.unmockkAll
+import io.mockk.verify
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+private const val A_SESSION_ID = "session_id"
+
+class SessionOverviewViewNavigatorTest {
+
+ private val context = FakeContext()
+ private val sessionOverviewViewNavigator = SessionOverviewViewNavigator()
+
+ @Before
+ fun setUp() {
+ mockkObject(SessionDetailsActivity)
+ }
+
+ @After
+ fun tearDown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun `given a session id when navigating to details then it starts the correct activity`() {
+ // Given
+ val intent = givenIntentForSessionDetails(A_SESSION_ID)
+ context.givenStartActivity(intent)
+
+ // When
+ sessionOverviewViewNavigator.navigateToSessionDetails(context.instance, A_SESSION_ID)
+
+ // Then
+ verify {
+ context.instance.startActivity(intent)
+ }
+ }
+
+ private fun givenIntentForSessionDetails(sessionId: String): Intent {
+ val intent = mockk()
+ every { SessionDetailsActivity.newIntent(context.instance, sessionId) } returns intent
+ return intent
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeClipboardManager.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeClipboardManager.kt
new file mode 100644
index 0000000000..983902b496
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeClipboardManager.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.test.fakes
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import io.mockk.every
+import io.mockk.just
+import io.mockk.mockk
+import io.mockk.runs
+import io.mockk.verify
+
+class FakeClipboardManager {
+ val instance = mockk()
+
+ fun givenSetPrimaryClip() {
+ every { instance.setPrimaryClip(any()) } just runs
+ }
+
+ fun verifySetPrimaryClip(clipData: ClipData) {
+ verify { instance.setPrimaryClip(clipData) }
+ }
+}
diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
index d74ebcb678..9a94313fec 100644
--- a/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
+++ b/vector/src/test/java/im/vector/app/test/fakes/FakeContext.kt
@@ -16,6 +16,7 @@
package im.vector.app.test.fakes
+import android.content.ClipboardManager
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
@@ -74,4 +75,10 @@ class FakeContext(
fun givenStartActivity(intent: Intent) {
every { instance.startActivity(intent) } just runs
}
+
+ fun givenClipboardManager(): FakeClipboardManager {
+ val fakeClipboardManager = FakeClipboardManager()
+ givenService(Context.CLIPBOARD_SERVICE, ClipboardManager::class.java, fakeClipboardManager.instance)
+ return fakeClipboardManager
+ }
}