Merge branch 'develop' into feature/bma/android12
This commit is contained in:
commit
b9c28ba4ce
|
@ -31,7 +31,7 @@ jobs:
|
||||||
ui-tests:
|
ui-tests:
|
||||||
name: UI Tests (Synapse)
|
name: UI Tests (Synapse)
|
||||||
needs: should-i-run
|
needs: should-i-run
|
||||||
runs-on: macos-latest
|
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
@ -13,7 +13,10 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
name: Runs all tests
|
name: Runs all tests
|
||||||
runs-on: macos-latest # for the emulator
|
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
api-level: [28]
|
||||||
# Allow all jobs on main and develop. Just one per PR.
|
# Allow all jobs on main and develop. Just one per PR.
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
|
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
|
||||||
|
@ -36,40 +39,70 @@ jobs:
|
||||||
httpPort: 8080
|
httpPort: 8080
|
||||||
disableRateLimiting: true
|
disableRateLimiting: true
|
||||||
public_baseurl: "http://10.0.2.2:8080/"
|
public_baseurl: "http://10.0.2.2:8080/"
|
||||||
|
|
||||||
|
- name: AVD cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: avd-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.android/avd/*
|
||||||
|
~/.android/adb*
|
||||||
|
key: avd-${{ matrix.api-level }}
|
||||||
|
|
||||||
|
- name: create AVD and generate snapshot for caching
|
||||||
|
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: ${{ matrix.api-level }}
|
||||||
|
arch: x86
|
||||||
|
profile: Nexus 5X
|
||||||
|
force-avd-creation: true # Is set to false in the doc https://github.com/ReactiveCircus/android-emulator-runner
|
||||||
|
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
|
disable-animations: true
|
||||||
|
script: echo "Generated AVD snapshot for caching."
|
||||||
|
|
||||||
- name: Run all the codecoverage tests at once
|
- name: Run all the codecoverage tests at once
|
||||||
id: tests
|
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
continue-on-error: true
|
# continue-on-error: true
|
||||||
with:
|
with:
|
||||||
api-level: 28
|
api-level: ${{ matrix.api-level }}
|
||||||
arch: x86
|
arch: x86
|
||||||
profile: Nexus 5X
|
profile: Nexus 5X
|
||||||
force-avd-creation: false
|
force-avd-creation: false
|
||||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
disable-animations: true
|
disable-animations: true
|
||||||
emulator-build: 7425822
|
# emulator-build: 7425822
|
||||||
script: |
|
script: |
|
||||||
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||||
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves stes.tests.outcome = 'failure'
|
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves steps.tests.outcome = 'failure'
|
||||||
- name: Run all the codecoverage tests at once (retry if emulator failed)
|
### - name: Run all the codecoverage tests at once (retry if emulator failed)
|
||||||
uses: reactivecircus/android-emulator-runner@v2
|
### uses: reactivecircus/android-emulator-runner@v2
|
||||||
if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
|
### if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
|
||||||
|
### with:
|
||||||
|
### api-level: 28
|
||||||
|
### arch: x86
|
||||||
|
### profile: Nexus 5X
|
||||||
|
### force-avd-creation: false
|
||||||
|
### emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||||
|
### disable-animations: true
|
||||||
|
### emulator-build: 7425822
|
||||||
|
### script: |
|
||||||
|
### ./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
### ./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
### ./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
### ./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||||
|
|
||||||
|
- name: Upload Integration Test Report Log
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
with:
|
with:
|
||||||
api-level: 28
|
name: integration-test-error-results
|
||||||
arch: x86
|
path: |
|
||||||
profile: Nexus 5X
|
*/build/outputs/androidTest-results/connected/
|
||||||
force-avd-creation: false
|
*/build/reports/androidTests/connected/
|
||||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
|
||||||
disable-animations: true
|
|
||||||
emulator-build: 7425822
|
|
||||||
script: |
|
|
||||||
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
|
||||||
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
|
||||||
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
|
||||||
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
|
||||||
|
|
||||||
# we may have failed a previous step and retried, that's OK
|
# we may have failed a previous step and retried, that's OK
|
||||||
- name: Publish results to Sonar
|
- name: Publish results to Sonar
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Create DM room only on first message - Add a spinner when sending the first message
|
|
@ -0,0 +1 @@
|
||||||
|
[Device Manager] Filter Other Sessions
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed problem when room list's scroll did jump after rooms placeholders were replaced with rooms summary items
|
|
@ -0,0 +1 @@
|
||||||
|
Move some GitHub actions to buildjet runners, and remove the second attempt to run integration tests.
|
|
@ -0,0 +1 @@
|
||||||
|
Create DM room only on first message - Handle the local rooms within the new AppLayout
|
|
@ -0,0 +1 @@
|
||||||
|
New App Layout is now enabled by default! Go to the Settings > Labs to toggle this
|
|
@ -0,0 +1 @@
|
||||||
|
Deferred DMs - Enable and move the feature to labs settings
|
|
@ -0,0 +1 @@
|
||||||
|
Fixes Room List not getting updated when fragment is not in focus
|
|
@ -320,7 +320,7 @@
|
||||||
<string name="settings_theme">السمة</string>
|
<string name="settings_theme">السمة</string>
|
||||||
<string name="encryption_information_decryption_error">خطأ في فكّ التعمية</string>
|
<string name="encryption_information_decryption_error">خطأ في فكّ التعمية</string>
|
||||||
<string name="encryption_information_device_name">اسم الجهاز</string>
|
<string name="encryption_information_device_name">اسم الجهاز</string>
|
||||||
<string name="device_manager_session_details_session_id">معرّف الجهاز</string>
|
<string name="encryption_information_device_id">معرّف الجهاز</string>
|
||||||
<string name="encryption_information_device_key">مفتاح الجهاز</string>
|
<string name="encryption_information_device_key">مفتاح الجهاز</string>
|
||||||
<string name="encryption_export_room_keys">صدّر مفاتيح الغرفة</string>
|
<string name="encryption_export_room_keys">صدّر مفاتيح الغرفة</string>
|
||||||
<string name="encryption_export_room_keys_summary">صدّر المفاتيح إلى ملف محلي</string>
|
<string name="encryption_export_room_keys_summary">صدّر المفاتيح إلى ملف محلي</string>
|
||||||
|
|
|
@ -396,7 +396,7 @@
|
||||||
<string name="settings_theme">Тема</string>
|
<string name="settings_theme">Тема</string>
|
||||||
<string name="encryption_information_decryption_error">Грешка при разшифроване</string>
|
<string name="encryption_information_decryption_error">Грешка при разшифроване</string>
|
||||||
<string name="encryption_information_device_name">Публично име</string>
|
<string name="encryption_information_device_name">Публично име</string>
|
||||||
<string name="device_manager_session_details_session_id">Сесийно ID</string>
|
<string name="encryption_information_device_id">Сесийно ID</string>
|
||||||
<string name="encryption_information_device_key">Ключ на устройство</string>
|
<string name="encryption_information_device_key">Ключ на устройство</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Експортирай E2E ключове за стая</string>
|
<string name="encryption_export_e2e_room_keys">Експортирай E2E ключове за стая</string>
|
||||||
<string name="encryption_export_room_keys">Експортиране на ключове за стая</string>
|
<string name="encryption_export_room_keys">Експортиране на ключове за стая</string>
|
||||||
|
|
|
@ -789,7 +789,7 @@
|
||||||
<string name="encryption_export_room_keys">রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
<string name="encryption_export_room_keys">রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
||||||
<string name="encryption_export_e2e_room_keys">শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
<string name="encryption_export_e2e_room_keys">শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
||||||
<string name="encryption_information_device_key">সেশানের কুঞ্জি</string>
|
<string name="encryption_information_device_key">সেশানের কুঞ্জি</string>
|
||||||
<string name="device_manager_session_details_session_id">আইডি</string>
|
<string name="encryption_information_device_id">আইডি</string>
|
||||||
<string name="encryption_information_device_name">সর্বজনীন নাম</string>
|
<string name="encryption_information_device_name">সর্বজনীন নাম</string>
|
||||||
<string name="encryption_information_decryption_error">ডিক্রিপশন সমস্যা</string>
|
<string name="encryption_information_decryption_error">ডিক্রিপশন সমস্যা</string>
|
||||||
<string name="settings_theme">থিম</string>
|
<string name="settings_theme">থিম</string>
|
||||||
|
|
|
@ -693,7 +693,7 @@
|
||||||
<string name="encryption_information_decryption_error">ডিক্রিপশন সমস্যা</string>
|
<string name="encryption_information_decryption_error">ডিক্রিপশন সমস্যা</string>
|
||||||
|
|
||||||
<string name="encryption_information_device_name">সর্বজনীন নাম</string>
|
<string name="encryption_information_device_name">সর্বজনীন নাম</string>
|
||||||
<string name="device_manager_session_details_session_id">আইডি</string>
|
<string name="encryption_information_device_id">আইডি</string>
|
||||||
<string name="encryption_information_device_key">সেশানের কুঞ্জি</string>
|
<string name="encryption_information_device_key">সেশানের কুঞ্জি</string>
|
||||||
|
|
||||||
<string name="encryption_export_e2e_room_keys">শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
<string name="encryption_export_e2e_room_keys">শেষ থেকে শেষ রুমের কুঞ্জিগুলি এক্সপোর্ট করুন</string>
|
||||||
|
|
|
@ -448,7 +448,7 @@
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Error al desxifrar</string>
|
<string name="encryption_information_decryption_error">Error al desxifrar</string>
|
||||||
<string name="encryption_information_device_name">Nom públic</string>
|
<string name="encryption_information_device_name">Nom públic</string>
|
||||||
<string name="device_manager_session_details_session_id">ID de sessió</string>
|
<string name="encryption_information_device_id">ID de sessió</string>
|
||||||
<string name="encryption_information_device_key">Clau de sessió</string>
|
<string name="encryption_information_device_key">Clau de sessió</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exporta les claus de la sala E2E</string>
|
<string name="encryption_export_e2e_room_keys">Exporta les claus de la sala E2E</string>
|
||||||
<string name="encryption_export_room_keys">Exporta les claus de la sala</string>
|
<string name="encryption_export_room_keys">Exporta les claus de la sala</string>
|
||||||
|
|
|
@ -635,7 +635,7 @@
|
||||||
<string name="settings_theme">Motiv vzhledu</string>
|
<string name="settings_theme">Motiv vzhledu</string>
|
||||||
<string name="encryption_information_decryption_error">Chyba dešifrování</string>
|
<string name="encryption_information_decryption_error">Chyba dešifrování</string>
|
||||||
<string name="encryption_information_device_name">Veřejné jméno</string>
|
<string name="encryption_information_device_name">Veřejné jméno</string>
|
||||||
<string name="device_manager_session_details_session_id">ID relace</string>
|
<string name="encryption_information_device_id">ID relace</string>
|
||||||
<string name="encryption_information_device_key">Klíč relace</string>
|
<string name="encryption_information_device_key">Klíč relace</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Export E2E klíčů místností</string>
|
<string name="encryption_export_e2e_room_keys">Export E2E klíčů místností</string>
|
||||||
<string name="encryption_export_room_keys">Export klíčů místností</string>
|
<string name="encryption_export_room_keys">Export klíčů místností</string>
|
||||||
|
|
|
@ -418,7 +418,7 @@
|
||||||
<string name="room_settings_unset_main_address">Als Hauptadresse aufheben</string>
|
<string name="room_settings_unset_main_address">Als Hauptadresse aufheben</string>
|
||||||
<string name="encryption_information_decryption_error">Entschlüsselungsfehler</string>
|
<string name="encryption_information_decryption_error">Entschlüsselungsfehler</string>
|
||||||
<string name="encryption_information_device_name">Öffentlicher Name</string>
|
<string name="encryption_information_device_name">Öffentlicher Name</string>
|
||||||
<string name="device_manager_session_details_session_id">Sitzungs-ID</string>
|
<string name="encryption_information_device_id">Sitzungs-ID</string>
|
||||||
<string name="encryption_information_device_key">Sitzungsschlüssel</string>
|
<string name="encryption_information_device_key">Sitzungsschlüssel</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Ende-zu-Ende-Raumschlüssel exportieren</string>
|
<string name="encryption_export_e2e_room_keys">Ende-zu-Ende-Raumschlüssel exportieren</string>
|
||||||
<string name="encryption_export_room_keys">Raumschlüssel exportieren</string>
|
<string name="encryption_export_room_keys">Raumschlüssel exportieren</string>
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
<string name="settings_theme">Θέμα</string>
|
<string name="settings_theme">Θέμα</string>
|
||||||
<string name="encryption_information_decryption_error">Σφάλμα αποκρυπτογράφησης</string>
|
<string name="encryption_information_decryption_error">Σφάλμα αποκρυπτογράφησης</string>
|
||||||
<string name="encryption_information_device_name">Όνομα συσκευής</string>
|
<string name="encryption_information_device_name">Όνομα συσκευής</string>
|
||||||
<string name="device_manager_session_details_session_id">Αναγνωριστικό συσκευής</string>
|
<string name="encryption_information_device_id">Αναγνωριστικό συσκευής</string>
|
||||||
<string name="encryption_export_export">Εξαγωγή</string>
|
<string name="encryption_export_export">Εξαγωγή</string>
|
||||||
<string name="encryption_import_import">Εισαγωγή</string>
|
<string name="encryption_import_import">Εισαγωγή</string>
|
||||||
<string name="select_room_directory">Επιλέξτε ένα ευρετήριο δωματίων</string>
|
<string name="select_room_directory">Επιλέξτε ένα ευρετήριο δωματίων</string>
|
||||||
|
|
|
@ -1084,7 +1084,7 @@
|
||||||
<string name="encryption_export_room_keys">Elporti ŝlosilojn de ĉambroj</string>
|
<string name="encryption_export_room_keys">Elporti ŝlosilojn de ĉambroj</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Elporti tutvoje ĉifrajn ŝlosilojn de ĉambroj</string>
|
<string name="encryption_export_e2e_room_keys">Elporti tutvoje ĉifrajn ŝlosilojn de ĉambroj</string>
|
||||||
<string name="encryption_information_device_key">Ŝlosilo de salutaĵo</string>
|
<string name="encryption_information_device_key">Ŝlosilo de salutaĵo</string>
|
||||||
<string name="device_manager_session_details_session_id">Identigilo de salutaĵo</string>
|
<string name="encryption_information_device_id">Identigilo de salutaĵo</string>
|
||||||
<string name="encryption_information_device_name">Publika nomo</string>
|
<string name="encryption_information_device_name">Publika nomo</string>
|
||||||
<string name="encryption_information_decryption_error">Eraris malĉifrado</string>
|
<string name="encryption_information_decryption_error">Eraris malĉifrado</string>
|
||||||
<string name="settings_theme">Haŭto</string>
|
<string name="settings_theme">Haŭto</string>
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
<string name="room_settings_unset_main_address">Desescojer como Dirección Principal</string>
|
<string name="room_settings_unset_main_address">Desescojer como Dirección Principal</string>
|
||||||
<string name="encryption_information_decryption_error">Error en descifrar</string>
|
<string name="encryption_information_decryption_error">Error en descifrar</string>
|
||||||
<string name="encryption_information_device_name">Nombre del dispositivo</string>
|
<string name="encryption_information_device_name">Nombre del dispositivo</string>
|
||||||
<string name="device_manager_session_details_session_id">Identificación del dispositivo</string>
|
<string name="encryption_information_device_id">Identificación del dispositivo</string>
|
||||||
<string name="encryption_information_device_key">Clave del dispositivo</string>
|
<string name="encryption_information_device_key">Clave del dispositivo</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportar claves de cifrado de extremo-a-extremo de salas</string>
|
<string name="encryption_export_e2e_room_keys">Exportar claves de cifrado de extremo-a-extremo de salas</string>
|
||||||
<string name="encryption_export_room_keys">Exportar claves de salas</string>
|
<string name="encryption_export_room_keys">Exportar claves de salas</string>
|
||||||
|
|
|
@ -415,7 +415,7 @@
|
||||||
<string name="room_settings_unset_main_address">Dejar de Establecer como dirección principal</string>
|
<string name="room_settings_unset_main_address">Dejar de Establecer como dirección principal</string>
|
||||||
<string name="encryption_information_decryption_error">Error de descifrado</string>
|
<string name="encryption_information_decryption_error">Error de descifrado</string>
|
||||||
<string name="encryption_information_device_name">Nombre público</string>
|
<string name="encryption_information_device_name">Nombre público</string>
|
||||||
<string name="device_manager_session_details_session_id">ID de sesión</string>
|
<string name="encryption_information_device_id">ID de sesión</string>
|
||||||
<string name="encryption_information_device_key">Clave de sesión</string>
|
<string name="encryption_information_device_key">Clave de sesión</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportar claves de salas con cifrado Extremo-a-Extremo</string>
|
<string name="encryption_export_e2e_room_keys">Exportar claves de salas con cifrado Extremo-a-Extremo</string>
|
||||||
<string name="encryption_export_room_keys">Exportar claves de sala</string>
|
<string name="encryption_export_room_keys">Exportar claves de sala</string>
|
||||||
|
|
|
@ -612,7 +612,7 @@
|
||||||
<string name="room_settings_labs_warning_message">Need on alles katsejärgus olevad funktsionaalsused. Ole kasutamisel ettevaatlik.</string>
|
<string name="room_settings_labs_warning_message">Need on alles katsejärgus olevad funktsionaalsused. Ole kasutamisel ettevaatlik.</string>
|
||||||
<string name="encryption_information_decryption_error">Dekrüptimise viga</string>
|
<string name="encryption_information_decryption_error">Dekrüptimise viga</string>
|
||||||
<string name="encryption_information_device_name">Avalik nimi</string>
|
<string name="encryption_information_device_name">Avalik nimi</string>
|
||||||
<string name="device_manager_session_details_session_id">Sessiooni tunnus</string>
|
<string name="encryption_information_device_id">Sessiooni tunnus</string>
|
||||||
<string name="encryption_information_device_key">Sessiooni võti</string>
|
<string name="encryption_information_device_key">Sessiooni võti</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Ekspordi jututubade läbiva krüptimise võtmed</string>
|
<string name="encryption_export_e2e_room_keys">Ekspordi jututubade läbiva krüptimise võtmed</string>
|
||||||
<string name="encryption_export_room_keys">Ekspordi jututoa võtmed</string>
|
<string name="encryption_export_room_keys">Ekspordi jututoa võtmed</string>
|
||||||
|
|
|
@ -406,7 +406,7 @@ Kontuan izan ekintza honek aplikazioa berrabiaraziko duela eta denbora bat behar
|
||||||
<string name="encryption_information_decryption_error">Deszifratze errorea</string>
|
<string name="encryption_information_decryption_error">Deszifratze errorea</string>
|
||||||
|
|
||||||
<string name="encryption_information_device_name">Izen publikoa</string>
|
<string name="encryption_information_device_name">Izen publikoa</string>
|
||||||
<string name="device_manager_session_details_session_id">IDa</string>
|
<string name="encryption_information_device_id">IDa</string>
|
||||||
<string name="encryption_information_device_key">Saioaren gakoa</string>
|
<string name="encryption_information_device_key">Saioaren gakoa</string>
|
||||||
|
|
||||||
<string name="encryption_export_e2e_room_keys">Esportatu E2E geletako gakoak</string>
|
<string name="encryption_export_e2e_room_keys">Esportatu E2E geletako gakoak</string>
|
||||||
|
|
|
@ -678,7 +678,7 @@
|
||||||
<string name="room_settings_labs_warning_message">اینها ویژگیهای آزمایشیای هستند که ممکن است به روشهای نامنتظرهای حراب شوندا. با احتیاط استفاده کنید.</string>
|
<string name="room_settings_labs_warning_message">اینها ویژگیهای آزمایشیای هستند که ممکن است به روشهای نامنتظرهای حراب شوندا. با احتیاط استفاده کنید.</string>
|
||||||
<string name="room_settings_set_main_address">تنظیم به عنوان نشانی اصلی</string>
|
<string name="room_settings_set_main_address">تنظیم به عنوان نشانی اصلی</string>
|
||||||
<string name="encryption_information_device_name">نام عمومی</string>
|
<string name="encryption_information_device_name">نام عمومی</string>
|
||||||
<string name="device_manager_session_details_session_id">شناسهٔ نشست</string>
|
<string name="encryption_information_device_id">شناسهٔ نشست</string>
|
||||||
<string name="encryption_information_device_key">کلید نشست</string>
|
<string name="encryption_information_device_key">کلید نشست</string>
|
||||||
<string name="encryption_export_e2e_room_keys">برونریزی کلیدهای اتاقهای سرتاسری</string>
|
<string name="encryption_export_e2e_room_keys">برونریزی کلیدهای اتاقهای سرتاسری</string>
|
||||||
<string name="encryption_export_room_keys">برونریزی کلیدهای اتاقها</string>
|
<string name="encryption_export_room_keys">برونریزی کلیدهای اتاقها</string>
|
||||||
|
|
|
@ -366,7 +366,7 @@
|
||||||
<string name="room_settings_unset_main_address">Kumoa pääosoitteeksi asettaminen</string>
|
<string name="room_settings_unset_main_address">Kumoa pääosoitteeksi asettaminen</string>
|
||||||
<string name="encryption_information_decryption_error">Salauksenpurkuvirhe</string>
|
<string name="encryption_information_decryption_error">Salauksenpurkuvirhe</string>
|
||||||
<string name="encryption_information_device_name">Julkinen nimi</string>
|
<string name="encryption_information_device_name">Julkinen nimi</string>
|
||||||
<string name="device_manager_session_details_session_id">Istunnon tunnus</string>
|
<string name="encryption_information_device_id">Istunnon tunnus</string>
|
||||||
<string name="encryption_information_device_key">Istunnon avain</string>
|
<string name="encryption_information_device_key">Istunnon avain</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Vie salatun huoneen avaimet</string>
|
<string name="encryption_export_e2e_room_keys">Vie salatun huoneen avaimet</string>
|
||||||
<string name="encryption_export_room_keys">Vie huoneen avaimet</string>
|
<string name="encryption_export_room_keys">Vie huoneen avaimet</string>
|
||||||
|
|
|
@ -778,7 +778,7 @@
|
||||||
<string name="encryption_export_room_keys">Exporter les clés des salons</string>
|
<string name="encryption_export_room_keys">Exporter les clés des salons</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exporter les clés E2E des salons</string>
|
<string name="encryption_export_e2e_room_keys">Exporter les clés E2E des salons</string>
|
||||||
<string name="encryption_information_device_key">Clé de la session</string>
|
<string name="encryption_information_device_key">Clé de la session</string>
|
||||||
<string name="device_manager_session_details_session_id">Identifiant de session</string>
|
<string name="encryption_information_device_id">Identifiant de session</string>
|
||||||
<string name="encryption_information_device_name">Nom public</string>
|
<string name="encryption_information_device_name">Nom public</string>
|
||||||
<string name="encryption_information_decryption_error">Erreur de déchiffrement</string>
|
<string name="encryption_information_decryption_error">Erreur de déchiffrement</string>
|
||||||
<string name="settings_theme">Thème</string>
|
<string name="settings_theme">Thème</string>
|
||||||
|
|
|
@ -346,7 +346,7 @@
|
||||||
<string name="room_settings_unset_main_address">Désactiver comme adresse principale</string>
|
<string name="room_settings_unset_main_address">Désactiver comme adresse principale</string>
|
||||||
<string name="encryption_information_decryption_error">Erreur de déchiffrement</string>
|
<string name="encryption_information_decryption_error">Erreur de déchiffrement</string>
|
||||||
<string name="encryption_information_device_name">Nom public</string>
|
<string name="encryption_information_device_name">Nom public</string>
|
||||||
<string name="device_manager_session_details_session_id">Identifiant de session</string>
|
<string name="encryption_information_device_id">Identifiant de session</string>
|
||||||
<string name="encryption_information_device_key">Clé de la session</string>
|
<string name="encryption_information_device_key">Clé de la session</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exporter les clés E2E des salons</string>
|
<string name="encryption_export_e2e_room_keys">Exporter les clés E2E des salons</string>
|
||||||
<string name="encryption_export_room_keys">Exporter les clés des salons</string>
|
<string name="encryption_export_room_keys">Exporter les clés des salons</string>
|
||||||
|
|
|
@ -380,7 +380,7 @@
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Fallo ao descifrar</string>
|
<string name="encryption_information_decryption_error">Fallo ao descifrar</string>
|
||||||
<string name="encryption_information_device_name">Nome do dispositivo</string>
|
<string name="encryption_information_device_name">Nome do dispositivo</string>
|
||||||
<string name="device_manager_session_details_session_id">ID de sesión</string>
|
<string name="encryption_information_device_id">ID de sesión</string>
|
||||||
<string name="encryption_information_device_key">Chave do dispositivo</string>
|
<string name="encryption_information_device_key">Chave do dispositivo</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportar chaves E2E da sala</string>
|
<string name="encryption_export_e2e_room_keys">Exportar chaves E2E da sala</string>
|
||||||
<string name="encryption_export_room_keys">Exportar chaves da sala</string>
|
<string name="encryption_export_room_keys">Exportar chaves da sala</string>
|
||||||
|
|
|
@ -572,7 +572,7 @@
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Greška u dešifriranju</string>
|
<string name="encryption_information_decryption_error">Greška u dešifriranju</string>
|
||||||
<string name="encryption_information_device_name">Javni naziv</string>
|
<string name="encryption_information_device_name">Javni naziv</string>
|
||||||
<string name="device_manager_session_details_session_id">Identitet</string>
|
<string name="encryption_information_device_id">Identitet</string>
|
||||||
<string name="encryption_information_device_key">Ključ sesije</string>
|
<string name="encryption_information_device_key">Ključ sesije</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Izvezi sobne ključeve za E2E</string>
|
<string name="encryption_export_e2e_room_keys">Izvezi sobne ključeve za E2E</string>
|
||||||
<string name="encryption_export_room_keys">Izvezi sobne ključeve</string>
|
<string name="encryption_export_room_keys">Izvezi sobne ključeve</string>
|
||||||
|
|
|
@ -351,7 +351,7 @@
|
||||||
<string name="room_settings_unset_main_address">Kiszedés fő címek közül</string>
|
<string name="room_settings_unset_main_address">Kiszedés fő címek közül</string>
|
||||||
<string name="encryption_information_decryption_error">Visszafejtés hiba</string>
|
<string name="encryption_information_decryption_error">Visszafejtés hiba</string>
|
||||||
<string name="encryption_information_device_name">Nyilvános név</string>
|
<string name="encryption_information_device_name">Nyilvános név</string>
|
||||||
<string name="device_manager_session_details_session_id">Munkamenet-azonosító</string>
|
<string name="encryption_information_device_id">Munkamenet-azonosító</string>
|
||||||
<string name="encryption_information_device_key">Munkamenet kulcs</string>
|
<string name="encryption_information_device_key">Munkamenet kulcs</string>
|
||||||
<string name="encryption_export_e2e_room_keys">E2E szoba kulcsok exportálása</string>
|
<string name="encryption_export_e2e_room_keys">E2E szoba kulcsok exportálása</string>
|
||||||
<string name="encryption_export_room_keys">Szoba kulcsok exportálása</string>
|
<string name="encryption_export_room_keys">Szoba kulcsok exportálása</string>
|
||||||
|
|
|
@ -301,7 +301,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string>
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Kesalahan dekripsi</string>
|
<string name="encryption_information_decryption_error">Kesalahan dekripsi</string>
|
||||||
<string name="encryption_information_device_name">Nama perangkat</string>
|
<string name="encryption_information_device_name">Nama perangkat</string>
|
||||||
<string name="device_manager_session_details_session_id">ID Sesi</string>
|
<string name="encryption_information_device_id">ID Sesi</string>
|
||||||
<string name="encryption_information_device_key">Kunci perangkat</string>
|
<string name="encryption_information_device_key">Kunci perangkat</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Ekspor kunci ruangan terenkripsi</string>
|
<string name="encryption_export_e2e_room_keys">Ekspor kunci ruangan terenkripsi</string>
|
||||||
<string name="encryption_export_room_keys">Ekspor ruangan kunci</string>
|
<string name="encryption_export_room_keys">Ekspor ruangan kunci</string>
|
||||||
|
|
|
@ -193,7 +193,7 @@
|
||||||
<string name="settings_theme">Þema</string>
|
<string name="settings_theme">Þema</string>
|
||||||
<string name="encryption_information_decryption_error">Afkóðunarvilla</string>
|
<string name="encryption_information_decryption_error">Afkóðunarvilla</string>
|
||||||
<string name="encryption_information_device_name">Heiti tækis</string>
|
<string name="encryption_information_device_name">Heiti tækis</string>
|
||||||
<string name="device_manager_session_details_session_id">Auðkenni setu</string>
|
<string name="encryption_information_device_id">Auðkenni setu</string>
|
||||||
<string name="encryption_information_device_key">Dulritunarlykill setu</string>
|
<string name="encryption_information_device_key">Dulritunarlykill setu</string>
|
||||||
<string name="encryption_export_export">Flytja út</string>
|
<string name="encryption_export_export">Flytja út</string>
|
||||||
<string name="passphrase_enter_passphrase">Settu inn lykilsetningu</string>
|
<string name="passphrase_enter_passphrase">Settu inn lykilsetningu</string>
|
||||||
|
|
|
@ -430,7 +430,7 @@
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Errore di decriptazione</string>
|
<string name="encryption_information_decryption_error">Errore di decriptazione</string>
|
||||||
<string name="encryption_information_device_name">Nome pubblico</string>
|
<string name="encryption_information_device_name">Nome pubblico</string>
|
||||||
<string name="device_manager_session_details_session_id">ID sessione</string>
|
<string name="encryption_information_device_id">ID sessione</string>
|
||||||
<string name="encryption_information_device_key">Chiave sessione</string>
|
<string name="encryption_information_device_key">Chiave sessione</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Esporta le chiavi di crittografia E2E delle stanze</string>
|
<string name="encryption_export_e2e_room_keys">Esporta le chiavi di crittografia E2E delle stanze</string>
|
||||||
<string name="encryption_export_room_keys">Esporta le chiavi delle stanze</string>
|
<string name="encryption_export_room_keys">Esporta le chiavi delle stanze</string>
|
||||||
|
|
|
@ -542,7 +542,7 @@
|
||||||
<string name="encryption_export_room_keys">יצא מפתחות חדר</string>
|
<string name="encryption_export_room_keys">יצא מפתחות חדר</string>
|
||||||
<string name="encryption_export_e2e_room_keys">ייצא מפתחות חדר E2E</string>
|
<string name="encryption_export_e2e_room_keys">ייצא מפתחות חדר E2E</string>
|
||||||
<string name="encryption_information_device_key">מזהה מפתח</string>
|
<string name="encryption_information_device_key">מזהה מפתח</string>
|
||||||
<string name="device_manager_session_details_session_id">מזהה מושב</string>
|
<string name="encryption_information_device_id">מזהה מושב</string>
|
||||||
<string name="encryption_information_device_name">שם ציבורי</string>
|
<string name="encryption_information_device_name">שם ציבורי</string>
|
||||||
<string name="encryption_information_decryption_error">שגיאת פענוח</string>
|
<string name="encryption_information_decryption_error">שגיאת פענוח</string>
|
||||||
<string name="settings_theme">ערכת נושא</string>
|
<string name="settings_theme">ערכת נושא</string>
|
||||||
|
|
|
@ -197,7 +197,7 @@
|
||||||
<string name="room_settings_labs_warning_message">これらは予期しない不具合が生じるかもしれない実験的機能です。慎重に使用してください。</string>
|
<string name="room_settings_labs_warning_message">これらは予期しない不具合が生じるかもしれない実験的機能です。慎重に使用してください。</string>
|
||||||
<string name="room_settings_set_main_address">メインアドレスとして設定</string>
|
<string name="room_settings_set_main_address">メインアドレスとして設定</string>
|
||||||
<string name="room_settings_unset_main_address">メインアドレスとしての設定を解除</string>
|
<string name="room_settings_unset_main_address">メインアドレスとしての設定を解除</string>
|
||||||
<string name="device_manager_session_details_session_id">セッションID</string>
|
<string name="encryption_information_device_id">セッションID</string>
|
||||||
<string name="font_size">文字の大きさ</string>
|
<string name="font_size">文字の大きさ</string>
|
||||||
<string name="tiny">とても小さい</string>
|
<string name="tiny">とても小さい</string>
|
||||||
<string name="small">小さい</string>
|
<string name="small">小さい</string>
|
||||||
|
|
|
@ -291,7 +291,7 @@
|
||||||
<string name="room_settings_category_advanced_title">Talqayt</string>
|
<string name="room_settings_category_advanced_title">Talqayt</string>
|
||||||
<string name="room_settings_labs_pref_title">Tinarimin</string>
|
<string name="room_settings_labs_pref_title">Tinarimin</string>
|
||||||
<string name="settings_theme">Asentel</string>
|
<string name="settings_theme">Asentel</string>
|
||||||
<string name="device_manager_session_details_session_id">Asulay n tqimit</string>
|
<string name="encryption_information_device_id">Asulay n tqimit</string>
|
||||||
<string name="encryption_information_device_key">Tasarut n tɣimit</string>
|
<string name="encryption_information_device_key">Tasarut n tɣimit</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Sifeḍ tisura n texxamt E2E</string>
|
<string name="encryption_export_e2e_room_keys">Sifeḍ tisura n texxamt E2E</string>
|
||||||
<string name="encryption_export_room_keys">Sifeḍ tisura n texxamt</string>
|
<string name="encryption_export_room_keys">Sifeḍ tisura n texxamt</string>
|
||||||
|
|
|
@ -431,7 +431,7 @@
|
||||||
<string name="settings_theme">테마</string>
|
<string name="settings_theme">테마</string>
|
||||||
<string name="encryption_information_decryption_error">암호 복호화 오류</string>
|
<string name="encryption_information_decryption_error">암호 복호화 오류</string>
|
||||||
<string name="encryption_information_device_name">공개 이름</string>
|
<string name="encryption_information_device_name">공개 이름</string>
|
||||||
<string name="device_manager_session_details_session_id">ID</string>
|
<string name="encryption_information_device_id">ID</string>
|
||||||
<string name="encryption_information_device_key">기기 키</string>
|
<string name="encryption_information_device_key">기기 키</string>
|
||||||
<string name="encryption_export_e2e_room_keys">종단간 암호화 방 키 내보내기</string>
|
<string name="encryption_export_e2e_room_keys">종단간 암호화 방 키 내보내기</string>
|
||||||
<string name="encryption_export_room_keys">방 키 내보내기</string>
|
<string name="encryption_export_room_keys">방 키 내보내기</string>
|
||||||
|
|
|
@ -909,7 +909,7 @@
|
||||||
<string name="encryption_export_room_keys">ສົ່ງອອກກະແຈຫ້ອງ</string>
|
<string name="encryption_export_room_keys">ສົ່ງອອກກະແຈຫ້ອງ</string>
|
||||||
<string name="encryption_export_e2e_room_keys">ສົ່ງອອກກະແຈຫ້ອງ E2E</string>
|
<string name="encryption_export_e2e_room_keys">ສົ່ງອອກກະແຈຫ້ອງ E2E</string>
|
||||||
<string name="encryption_information_device_key">ລະຫັດລະບົບ</string>
|
<string name="encryption_information_device_key">ລະຫັດລະບົບ</string>
|
||||||
<string name="device_manager_session_details_session_id">ID ລະບົບ</string>
|
<string name="encryption_information_device_id">ID ລະບົບ</string>
|
||||||
<string name="encryption_information_device_name">ຊື່ສາທາລະນະ</string>
|
<string name="encryption_information_device_name">ຊື່ສາທາລະນະ</string>
|
||||||
<string name="encryption_information_decryption_error">ການຖອດລະຫັດຜິດພາດ</string>
|
<string name="encryption_information_decryption_error">ການຖອດລະຫັດຜິດພາດ</string>
|
||||||
<string name="settings_theme">ຫົວຂໍ້</string>
|
<string name="settings_theme">ຫົວຂໍ້</string>
|
||||||
|
|
|
@ -469,7 +469,7 @@
|
||||||
<string name="settings_theme">Tēma</string>
|
<string name="settings_theme">Tēma</string>
|
||||||
<string name="encryption_information_decryption_error">Atšifrēšanas kļūda</string>
|
<string name="encryption_information_decryption_error">Atšifrēšanas kļūda</string>
|
||||||
<string name="encryption_information_device_name">Ierīces nosaukums</string>
|
<string name="encryption_information_device_name">Ierīces nosaukums</string>
|
||||||
<string name="device_manager_session_details_session_id">Sesijas ID</string>
|
<string name="encryption_information_device_id">Sesijas ID</string>
|
||||||
<string name="encryption_information_device_key">Sesijas atslēga</string>
|
<string name="encryption_information_device_key">Sesijas atslēga</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Eksportēt istabas šifrēšanas atslēgas</string>
|
<string name="encryption_export_e2e_room_keys">Eksportēt istabas šifrēšanas atslēgas</string>
|
||||||
<string name="encryption_export_room_keys">Eksportēt istabas atslēgas</string>
|
<string name="encryption_export_room_keys">Eksportēt istabas atslēgas</string>
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
<string name="room_settings_banned_users_title">Bannlyste brukere</string>
|
<string name="room_settings_banned_users_title">Bannlyste brukere</string>
|
||||||
<string name="room_settings_category_advanced_title">Avansert</string>
|
<string name="room_settings_category_advanced_title">Avansert</string>
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="device_manager_session_details_session_id">Økt-ID</string>
|
<string name="encryption_information_device_id">Økt-ID</string>
|
||||||
<string name="encryption_information_device_key">Øktnøkkel</string>
|
<string name="encryption_information_device_key">Øktnøkkel</string>
|
||||||
<string name="encryption_export_export">Eksporter</string>
|
<string name="encryption_export_export">Eksporter</string>
|
||||||
<string name="encryption_import_import">Importer</string>
|
<string name="encryption_import_import">Importer</string>
|
||||||
|
|
|
@ -275,7 +275,7 @@
|
||||||
<string name="room_settings_unset_main_address">Niet instellen als hoofdadres</string>
|
<string name="room_settings_unset_main_address">Niet instellen als hoofdadres</string>
|
||||||
<string name="encryption_information_decryption_error">Ontsleutelingsfout</string>
|
<string name="encryption_information_decryption_error">Ontsleutelingsfout</string>
|
||||||
<string name="encryption_information_device_name">Publieke naam</string>
|
<string name="encryption_information_device_name">Publieke naam</string>
|
||||||
<string name="device_manager_session_details_session_id">Sessie ID</string>
|
<string name="encryption_information_device_id">Sessie ID</string>
|
||||||
<string name="encryption_information_device_key">Sessiesleutel</string>
|
<string name="encryption_information_device_key">Sessiesleutel</string>
|
||||||
<string name="encryption_export_e2e_room_keys">E2E-gesprekssleutels exporteren</string>
|
<string name="encryption_export_e2e_room_keys">E2E-gesprekssleutels exporteren</string>
|
||||||
<string name="encryption_export_room_keys">Gesprekssleutels exporteren</string>
|
<string name="encryption_export_room_keys">Gesprekssleutels exporteren</string>
|
||||||
|
|
|
@ -310,7 +310,7 @@
|
||||||
<string name="settings_theme">Preg</string>
|
<string name="settings_theme">Preg</string>
|
||||||
<string name="encryption_information_decryption_error">Noko gjekk gale med dekrypteringa</string>
|
<string name="encryption_information_decryption_error">Noko gjekk gale med dekrypteringa</string>
|
||||||
<string name="encryption_information_device_name">Offentleg namn</string>
|
<string name="encryption_information_device_name">Offentleg namn</string>
|
||||||
<string name="device_manager_session_details_session_id">Økt-ID</string>
|
<string name="encryption_information_device_id">Økt-ID</string>
|
||||||
<string name="encryption_information_device_key">Sesjonsnøkkel</string>
|
<string name="encryption_information_device_key">Sesjonsnøkkel</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Eksporter E2E-romnøkklar</string>
|
<string name="encryption_export_e2e_room_keys">Eksporter E2E-romnøkklar</string>
|
||||||
<string name="encryption_export_room_keys">Eksporter romnøkklar</string>
|
<string name="encryption_export_room_keys">Eksporter romnøkklar</string>
|
||||||
|
|
|
@ -231,7 +231,7 @@
|
||||||
<string name="room_settings_set_main_address">Ustaw jako główny adres</string>
|
<string name="room_settings_set_main_address">Ustaw jako główny adres</string>
|
||||||
<string name="settings_theme">Motyw</string>
|
<string name="settings_theme">Motyw</string>
|
||||||
<string name="encryption_information_device_name">Nazwa publiczna</string>
|
<string name="encryption_information_device_name">Nazwa publiczna</string>
|
||||||
<string name="device_manager_session_details_session_id">ID sesji</string>
|
<string name="encryption_information_device_id">ID sesji</string>
|
||||||
<string name="encryption_export_export">Eksportuj</string>
|
<string name="encryption_export_export">Eksportuj</string>
|
||||||
<string name="passphrase_enter_passphrase">Wprowadź hasło</string>
|
<string name="passphrase_enter_passphrase">Wprowadź hasło</string>
|
||||||
<string name="passphrase_confirm_passphrase">Potwierdź hasło</string>
|
<string name="passphrase_confirm_passphrase">Potwierdź hasło</string>
|
||||||
|
|
|
@ -418,7 +418,7 @@
|
||||||
<string name="room_settings_unset_main_address">Des-definir como endereço principal</string>
|
<string name="room_settings_unset_main_address">Des-definir como endereço principal</string>
|
||||||
<string name="encryption_information_decryption_error">Erro de decriptação</string>
|
<string name="encryption_information_decryption_error">Erro de decriptação</string>
|
||||||
<string name="encryption_information_device_name">Nome público</string>
|
<string name="encryption_information_device_name">Nome público</string>
|
||||||
<string name="device_manager_session_details_session_id">ID de sessão</string>
|
<string name="encryption_information_device_id">ID de sessão</string>
|
||||||
<string name="encryption_information_device_key">Chave de sessão</string>
|
<string name="encryption_information_device_key">Chave de sessão</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportar chaves de sala E2E</string>
|
<string name="encryption_export_e2e_room_keys">Exportar chaves de sala E2E</string>
|
||||||
<string name="encryption_export_room_keys">Exportar chaves de sala</string>
|
<string name="encryption_export_room_keys">Exportar chaves de sala</string>
|
||||||
|
|
|
@ -246,7 +246,7 @@ Note que esta acção irá reiniciar a aplicação e poderá levar algum tempo.<
|
||||||
|
|
||||||
<string name="encryption_information_decryption_error">Erro de decifragem</string>
|
<string name="encryption_information_decryption_error">Erro de decifragem</string>
|
||||||
<string name="encryption_information_device_name">Nome do dispositivo</string>
|
<string name="encryption_information_device_name">Nome do dispositivo</string>
|
||||||
<string name="device_manager_session_details_session_id">ID do dispositivo</string>
|
<string name="encryption_information_device_id">ID do dispositivo</string>
|
||||||
<string name="encryption_information_device_key">Chave do dispositivo</string>
|
<string name="encryption_information_device_key">Chave do dispositivo</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportar chaves E2E da sala</string>
|
<string name="encryption_export_e2e_room_keys">Exportar chaves E2E da sala</string>
|
||||||
<string name="encryption_export_room_keys">Exportar chaves de sala</string>
|
<string name="encryption_export_room_keys">Exportar chaves de sala</string>
|
||||||
|
|
|
@ -432,7 +432,7 @@
|
||||||
<string name="room_settings_unset_main_address">Сбросить основной адрес</string>
|
<string name="room_settings_unset_main_address">Сбросить основной адрес</string>
|
||||||
<string name="encryption_information_decryption_error">Ошибка дешифровки</string>
|
<string name="encryption_information_decryption_error">Ошибка дешифровки</string>
|
||||||
<string name="encryption_information_device_name">Публичное имя</string>
|
<string name="encryption_information_device_name">Публичное имя</string>
|
||||||
<string name="device_manager_session_details_session_id">ID сессии</string>
|
<string name="encryption_information_device_id">ID сессии</string>
|
||||||
<string name="encryption_information_device_key">Ключ сессии</string>
|
<string name="encryption_information_device_key">Ключ сессии</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Экспорт E2E ключей комнаты</string>
|
<string name="encryption_export_e2e_room_keys">Экспорт E2E ключей комнаты</string>
|
||||||
<string name="encryption_export_room_keys">Экспорт ключей комнаты</string>
|
<string name="encryption_export_room_keys">Экспорт ключей комнаты</string>
|
||||||
|
|
|
@ -388,7 +388,7 @@
|
||||||
<string name="settings_theme">Vzhľad</string>
|
<string name="settings_theme">Vzhľad</string>
|
||||||
<string name="encryption_information_decryption_error">Chyba dešifrovania</string>
|
<string name="encryption_information_decryption_error">Chyba dešifrovania</string>
|
||||||
<string name="encryption_information_device_name">Verejné meno</string>
|
<string name="encryption_information_device_name">Verejné meno</string>
|
||||||
<string name="device_manager_session_details_session_id">ID relácie</string>
|
<string name="encryption_information_device_id">ID relácie</string>
|
||||||
<string name="encryption_information_device_key">Kľúč relácie</string>
|
<string name="encryption_information_device_key">Kľúč relácie</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportovať šifrovacie kľúče miestnosti</string>
|
<string name="encryption_export_e2e_room_keys">Exportovať šifrovacie kľúče miestnosti</string>
|
||||||
<string name="encryption_export_room_keys">Exportovať kľúče miestnosti</string>
|
<string name="encryption_export_room_keys">Exportovať kľúče miestnosti</string>
|
||||||
|
|
|
@ -431,7 +431,7 @@
|
||||||
<string name="settings_theme">Temë</string>
|
<string name="settings_theme">Temë</string>
|
||||||
<string name="encryption_information_decryption_error">Gabim shfshehtëzimi</string>
|
<string name="encryption_information_decryption_error">Gabim shfshehtëzimi</string>
|
||||||
<string name="encryption_information_device_name">Emër publik</string>
|
<string name="encryption_information_device_name">Emër publik</string>
|
||||||
<string name="device_manager_session_details_session_id">ID Sesioni</string>
|
<string name="encryption_information_device_id">ID Sesioni</string>
|
||||||
<string name="encryption_information_device_key">Kyç sesioni</string>
|
<string name="encryption_information_device_key">Kyç sesioni</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Eksporto kyçe dhome E2E</string>
|
<string name="encryption_export_e2e_room_keys">Eksporto kyçe dhome E2E</string>
|
||||||
<string name="encryption_export_room_keys">Eksporto kyçe dhome</string>
|
<string name="encryption_export_room_keys">Eksporto kyçe dhome</string>
|
||||||
|
|
|
@ -918,7 +918,7 @@
|
||||||
<string name="settings_secure_backup_enter_to_setup">Sätt upp på den här enheten</string>
|
<string name="settings_secure_backup_enter_to_setup">Sätt upp på den här enheten</string>
|
||||||
<string name="reset_secure_backup_title">Generera en ny säkerhetskopia eller sätt en ny lösenfras för din existerande säkerhetskopia.</string>
|
<string name="reset_secure_backup_title">Generera en ny säkerhetskopia eller sätt en ny lösenfras för din existerande säkerhetskopia.</string>
|
||||||
<string name="room_settings_labs_warning_message">Detta är experimentella funktioner som kan gå sönder på oväntade sätt. Använd varsamt.</string>
|
<string name="room_settings_labs_warning_message">Detta är experimentella funktioner som kan gå sönder på oväntade sätt. Använd varsamt.</string>
|
||||||
<string name="device_manager_session_details_session_id">Sessions-ID</string>
|
<string name="encryption_information_device_id">Sessions-ID</string>
|
||||||
<string name="encryption_information_device_key">Sessionsnyckel</string>
|
<string name="encryption_information_device_key">Sessionsnyckel</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Exportera krypteringsnycklar</string>
|
<string name="encryption_export_e2e_room_keys">Exportera krypteringsnycklar</string>
|
||||||
<string name="encryption_export_room_keys">Exportera rumsnycklar</string>
|
<string name="encryption_export_room_keys">Exportera rumsnycklar</string>
|
||||||
|
|
|
@ -260,7 +260,7 @@
|
||||||
<string name="room_settings_set_main_address">ప్రధాన చిరునామాగా సెట్ చేయండి</string>
|
<string name="room_settings_set_main_address">ప్రధాన చిరునామాగా సెట్ చేయండి</string>
|
||||||
|
|
||||||
<string name="encryption_information_device_name">పరికరం పేరు</string>
|
<string name="encryption_information_device_name">పరికరం పేరు</string>
|
||||||
<string name="device_manager_session_details_session_id">పరికరం ID</string>
|
<string name="encryption_information_device_id">పరికరం ID</string>
|
||||||
<string name="encryption_information_device_key">పరికరం కీ</string>
|
<string name="encryption_information_device_key">పరికరం కీ</string>
|
||||||
|
|
||||||
<string name="encryption_export_e2e_room_keys">E2E గది కీలను ఎగుమతి చేయండి</string>
|
<string name="encryption_export_e2e_room_keys">E2E గది కీలను ఎగుమతి చేయండి</string>
|
||||||
|
|
|
@ -376,7 +376,7 @@
|
||||||
<string name="settings_theme">Tema</string>
|
<string name="settings_theme">Tema</string>
|
||||||
<string name="encryption_information_decryption_error">Çözme hatası</string>
|
<string name="encryption_information_decryption_error">Çözme hatası</string>
|
||||||
<string name="encryption_information_device_name">Görünür Ad</string>
|
<string name="encryption_information_device_name">Görünür Ad</string>
|
||||||
<string name="device_manager_session_details_session_id">Oturum kimliği</string>
|
<string name="encryption_information_device_id">Oturum kimliği</string>
|
||||||
<string name="encryption_information_device_key">Oturum anahtarı</string>
|
<string name="encryption_information_device_key">Oturum anahtarı</string>
|
||||||
<string name="encryption_export_e2e_room_keys">E2E Oda anahtarlarını dışa aktar</string>
|
<string name="encryption_export_e2e_room_keys">E2E Oda anahtarlarını dışa aktar</string>
|
||||||
<string name="encryption_export_room_keys">Oda anahtarlarını dışa aktar</string>
|
<string name="encryption_export_room_keys">Oda anahtarlarını dışa aktar</string>
|
||||||
|
|
|
@ -354,7 +354,7 @@
|
||||||
<string name="room_settings_unset_main_address">Зробити не основною адресою</string>
|
<string name="room_settings_unset_main_address">Зробити не основною адресою</string>
|
||||||
<string name="encryption_information_decryption_error">Помилка розшифрування</string>
|
<string name="encryption_information_decryption_error">Помилка розшифрування</string>
|
||||||
<string name="encryption_information_device_name">Загальнодоступна назва</string>
|
<string name="encryption_information_device_name">Загальнодоступна назва</string>
|
||||||
<string name="device_manager_session_details_session_id">ID сеансу</string>
|
<string name="encryption_information_device_id">ID сеансу</string>
|
||||||
<string name="encryption_information_device_key">Ключ сеансу</string>
|
<string name="encryption_information_device_key">Ключ сеансу</string>
|
||||||
<string name="encryption_export_e2e_room_keys">Експортувати E2E ключі кімнати</string>
|
<string name="encryption_export_e2e_room_keys">Експортувати E2E ключі кімнати</string>
|
||||||
<string name="encryption_export_room_keys">Експортувати ключі кімнати</string>
|
<string name="encryption_export_room_keys">Експортувати ключі кімнати</string>
|
||||||
|
|
|
@ -594,7 +594,7 @@
|
||||||
<string name="deactivate_account_title">Hủy tài khoản</string>
|
<string name="deactivate_account_title">Hủy tài khoản</string>
|
||||||
<string name="dialog_user_consent_submit">Xem lại ngay</string>
|
<string name="dialog_user_consent_submit">Xem lại ngay</string>
|
||||||
<string name="encryption_information_device_key">Chìa khóa phiên</string>
|
<string name="encryption_information_device_key">Chìa khóa phiên</string>
|
||||||
<string name="device_manager_session_details_session_id">Mã phiên</string>
|
<string name="encryption_information_device_id">Mã phiên</string>
|
||||||
<string name="encryption_information_device_name">Tên công khai</string>
|
<string name="encryption_information_device_name">Tên công khai</string>
|
||||||
<string name="encryption_information_decryption_error">Lỗi giải mã</string>
|
<string name="encryption_information_decryption_error">Lỗi giải mã</string>
|
||||||
<string name="room_settings_labs_warning_message">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.</string>
|
<string name="room_settings_labs_warning_message">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.</string>
|
||||||
|
|
|
@ -242,7 +242,7 @@
|
||||||
<string name="settings_password_updated">你的密码已更新</string>
|
<string name="settings_password_updated">你的密码已更新</string>
|
||||||
<string name="encryption_information_decryption_error">解密错误</string>
|
<string name="encryption_information_decryption_error">解密错误</string>
|
||||||
<string name="encryption_information_device_name">公开名称</string>
|
<string name="encryption_information_device_name">公开名称</string>
|
||||||
<string name="device_manager_session_details_session_id">会话 ID</string>
|
<string name="encryption_information_device_id">会话 ID</string>
|
||||||
<string name="encryption_information_device_key">会话密钥</string>
|
<string name="encryption_information_device_key">会话密钥</string>
|
||||||
<string name="encryption_import_import">导入</string>
|
<string name="encryption_import_import">导入</string>
|
||||||
<string name="encryption_information_verified">已验证</string>
|
<string name="encryption_information_verified">已验证</string>
|
||||||
|
|
|
@ -469,7 +469,7 @@
|
||||||
<string name="settings_theme">主題</string>
|
<string name="settings_theme">主題</string>
|
||||||
<string name="encryption_information_decryption_error">解密錯誤</string>
|
<string name="encryption_information_decryption_error">解密錯誤</string>
|
||||||
<string name="encryption_information_device_name">公開名稱</string>
|
<string name="encryption_information_device_name">公開名稱</string>
|
||||||
<string name="device_manager_session_details_session_id">工作階段 ID</string>
|
<string name="encryption_information_device_id">工作階段 ID</string>
|
||||||
<string name="encryption_information_device_key">工作階段金鑰</string>
|
<string name="encryption_information_device_key">工作階段金鑰</string>
|
||||||
<string name="encryption_export_e2e_room_keys">匯出聊天室的端到端加密金鑰</string>
|
<string name="encryption_export_e2e_room_keys">匯出聊天室的端到端加密金鑰</string>
|
||||||
<string name="encryption_export_room_keys">匯出聊天室的加密金鑰</string>
|
<string name="encryption_export_room_keys">匯出聊天室的加密金鑰</string>
|
||||||
|
|
|
@ -442,6 +442,9 @@
|
||||||
<string name="labs_enable_new_app_layout_title">Enable new layout</string>
|
<string name="labs_enable_new_app_layout_title">Enable new layout</string>
|
||||||
<string name="labs_enable_new_app_layout_summary">A simplified Element with optional tabs</string>
|
<string name="labs_enable_new_app_layout_summary">A simplified Element with optional tabs</string>
|
||||||
|
|
||||||
|
<string name="labs_enable_deferred_dm_title">Enable deferred DMs</string>
|
||||||
|
<string name="labs_enable_deferred_dm_summary">Create DM only on first message</string>
|
||||||
|
|
||||||
<!-- Home fragment -->
|
<!-- Home fragment -->
|
||||||
<string name="invitations_header">Invites</string>
|
<string name="invitations_header">Invites</string>
|
||||||
<string name="low_priority_header">Low priority</string>
|
<string name="low_priority_header">Low priority</string>
|
||||||
|
@ -2361,7 +2364,9 @@
|
||||||
<string name="settings_active_sessions_manage">Manage Sessions</string>
|
<string name="settings_active_sessions_manage">Manage Sessions</string>
|
||||||
<string name="settings_active_sessions_signout_device">Sign out of this session</string>
|
<string name="settings_active_sessions_signout_device">Sign out of this session</string>
|
||||||
<string name="settings_sessions_list">Sessions</string>
|
<string name="settings_sessions_list">Sessions</string>
|
||||||
|
<!-- TODO rename to device_manager_sessions_other_title -->
|
||||||
<string name="settings_sessions_other_title">Other sessions</string>
|
<string name="settings_sessions_other_title">Other sessions</string>
|
||||||
|
<!-- TODO rename to device_manager_sessions_other_description -->
|
||||||
<string name="settings_sessions_other_description">For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore.</string>
|
<string name="settings_sessions_other_description">For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore.</string>
|
||||||
|
|
||||||
<string name="settings_server_name">Server name</string>
|
<string name="settings_server_name">Server name</string>
|
||||||
|
@ -3265,10 +3270,36 @@
|
||||||
<string name="device_manager_device_title">Device</string>
|
<string name="device_manager_device_title">Device</string>
|
||||||
<!-- Examples: Last activity Yesterday at 6PM, Last activity Aug 31 at 5:47PM -->
|
<!-- Examples: Last activity Yesterday at 6PM, Last activity Aug 31 at 5:47PM -->
|
||||||
<string name="device_manager_session_last_activity">Last activity %1$s</string>
|
<string name="device_manager_session_last_activity">Last activity %1$s</string>
|
||||||
|
<string name="device_manager_filter_bottom_sheet_title">Filter</string>
|
||||||
|
<string name="device_manager_filter_option_all_sessions">All sessions</string>
|
||||||
|
<string name="device_manager_filter_option_verified">Verified</string>
|
||||||
|
<string name="device_manager_filter_option_verified_description">Ready for secure messaging</string>
|
||||||
|
<string name="device_manager_filter_option_unverified">Unverified</string>
|
||||||
|
<string name="device_manager_filter_option_unverified_description">Not ready for secure messaging</string>
|
||||||
|
<string name="device_manager_filter_option_inactive">Inactive</string>
|
||||||
|
<plurals name="device_manager_filter_option_inactive_description">
|
||||||
|
<item quantity="one">Inactive for %1$d day or longer</item>
|
||||||
|
<item quantity="other">Inactive for %1$d days or longer</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="a11y_device_manager_filter">Filter</string>
|
||||||
|
<string name="device_manager_other_sessions_recommendation_title_verified">Verified</string>
|
||||||
|
<string name="device_manager_other_sessions_recommendation_description_verified">For best security, sign out from any session that you don’t recognize or use anymore.</string>
|
||||||
|
<string name="device_manager_other_sessions_recommendation_title_unverified">Unverified</string>
|
||||||
|
<string name="device_manager_other_sessions_recommendation_description_unverified">Verify your sessions for enhanced secure messaging or sign out from those you don’t recognize or use anymore.</string>
|
||||||
|
<string name="device_manager_other_sessions_recommendation_title_inactive">Inactive</string>
|
||||||
|
<plurals name="device_manager_other_sessions_recommendation_description_inactive">
|
||||||
|
<item quantity="one">Consider signing out from old sessions (%1$d day or more) you don’t use anymore.</item>
|
||||||
|
<item quantity="other">Consider signing out from old sessions (%1$d days or more) you don’t use anymore.</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="device_manager_other_sessions_no_verified_sessions_found">No verified sessions found.</string>
|
||||||
|
<string name="device_manager_other_sessions_no_unverified_sessions_found">No unverified sessions found.</string>
|
||||||
|
<string name="device_manager_other_sessions_no_inactive_sessions_found">No inactive sessions found.</string>
|
||||||
|
<string name="device_manager_other_sessions_clear_filter">Clear Filter</string>
|
||||||
<string name="device_manager_session_details_title">Session details</string>
|
<string name="device_manager_session_details_title">Session details</string>
|
||||||
<string name="device_manager_session_details_description">Application, device, and activity information.</string>
|
<string name="device_manager_session_details_description">Application, device, and activity information.</string>
|
||||||
<string name="device_manager_session_details_session_name">Session name</string>
|
<string name="device_manager_session_details_session_name">Session name</string>
|
||||||
<string name="device_manager_session_details_session_id">Session ID</string>
|
<!-- TODO rename to device_manager_session_details_session_id -->
|
||||||
|
<string name="encryption_information_device_id">Session ID</string>
|
||||||
<string name="device_manager_session_details_session_last_activity">Last activity</string>
|
<string name="device_manager_session_details_session_last_activity">Last activity</string>
|
||||||
<string name="device_manager_session_details_device_ip_address">IP address</string>
|
<string name="device_manager_session_details_device_ip_address">IP address</string>
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,7 @@
|
||||||
|
|
||||||
<!-- Shield colors -->
|
<!-- Shield colors -->
|
||||||
<color name="shield_color_trust">#0DBD8B</color>
|
<color name="shield_color_trust">#0DBD8B</color>
|
||||||
|
<color name="shield_color_trust_background">#0F0DBD8B</color>
|
||||||
<color name="shield_color_black">#17191C</color>
|
<color name="shield_color_black">#17191C</color>
|
||||||
<color name="shield_color_warning">#FF4B55</color>
|
<color name="shield_color_warning">#FF4B55</color>
|
||||||
<color name="shield_color_warning_background">#0FFF4B55</color>
|
<color name="shield_color_warning_background">#0FFF4B55</color>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<declare-styleable name="OtherSessionsSecurityRecommendationView">
|
||||||
|
<attr name="otherSessionsRecommendationTitle" format="string" />
|
||||||
|
<attr name="otherSessionsRecommendationDescription" format="string" />
|
||||||
|
<attr name="otherSessionsRecommendationImageResource" format="reference" />
|
||||||
|
<attr name="otherSessionsRecommendationImageBackgroundTint" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
|
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
@ -46,6 +47,13 @@ class FlowRoom(private val room: Room) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun liveLocalRoomSummary(): Flow<Optional<LocalRoomSummary>> {
|
||||||
|
return room.getLocalRoomSummaryLive().asFlow()
|
||||||
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
|
room.localRoomSummary().toOptional()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Flow<List<RoomMemberSummary>> {
|
fun liveRoomMembers(queryParams: RoomMemberQueryParams): Flow<List<RoomMemberSummary>> {
|
||||||
return room.membershipService().getRoomMembersLive(queryParams).asFlow()
|
return room.membershipService().getRoomMembersLive(queryParams).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.startWith(room.coroutineDispatchers.io) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
||||||
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
||||||
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
|
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
|
||||||
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationService
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationService
|
||||||
import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
|
import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
|
||||||
|
@ -60,11 +61,22 @@ interface Room {
|
||||||
*/
|
*/
|
||||||
fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>>
|
fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A live [LocalRoomSummary] associated with the room.
|
||||||
|
* You can observe this summary to get dynamic data from this room.
|
||||||
|
*/
|
||||||
|
fun getLocalRoomSummaryLive(): LiveData<Optional<LocalRoomSummary>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A current snapshot of [RoomSummary] associated with the room.
|
* A current snapshot of [RoomSummary] associated with the room.
|
||||||
*/
|
*/
|
||||||
fun roomSummary(): RoomSummary?
|
fun roomSummary(): RoomSummary?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A current snapshot of [LocalRoomSummary] associated with the room.
|
||||||
|
*/
|
||||||
|
fun localRoomSummary(): LocalRoomSummary?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this room as a Space, if the type is correct.
|
* Use this room as a Space, if the type is correct.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult
|
import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult
|
||||||
import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
@ -117,6 +118,12 @@ interface RoomService {
|
||||||
*/
|
*/
|
||||||
fun getRoomSummaryLive(roomId: String): LiveData<Optional<RoomSummary>>
|
fun getRoomSummaryLive(roomId: String): LiveData<Optional<RoomSummary>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A live [LocalRoomSummary] associated with the room with id [roomId].
|
||||||
|
* You can observe this summary to get dynamic data from this room, even if the room is not joined yet
|
||||||
|
*/
|
||||||
|
fun getLocalRoomSummaryLive(roomId: String): LiveData<Optional<LocalRoomSummary>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a snapshot list of room summaries.
|
* Get a snapshot list of room summaries.
|
||||||
* @return the immutable list of [RoomSummary]
|
* @return the immutable list of [RoomSummary]
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.room.model
|
||||||
|
|
||||||
|
enum class LocalRoomCreationState {
|
||||||
|
NOT_CREATED,
|
||||||
|
CREATING,
|
||||||
|
FAILURE,
|
||||||
|
CREATED
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.api.session.room.model
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class holds some data of a local room.
|
||||||
|
* It can be retrieved by [org.matrix.android.sdk.api.session.room.Room] and [org.matrix.android.sdk.api.session.room.RoomService]
|
||||||
|
*/
|
||||||
|
data class LocalRoomSummary(
|
||||||
|
/**
|
||||||
|
* The roomId of the room.
|
||||||
|
*/
|
||||||
|
val roomId: String,
|
||||||
|
/**
|
||||||
|
* The room summary of the room.
|
||||||
|
*/
|
||||||
|
val roomSummary: RoomSummary?,
|
||||||
|
/**
|
||||||
|
* The creation params attached to the room.
|
||||||
|
*/
|
||||||
|
val createRoomParams: CreateRoomParams?,
|
||||||
|
/**
|
||||||
|
* The roomId of the created room (ie. created on the server), if any.
|
||||||
|
*/
|
||||||
|
val replacementRoomId: String?,
|
||||||
|
/**
|
||||||
|
* The creation state of the room.
|
||||||
|
*/
|
||||||
|
val creationState: LocalRoomCreationState,
|
||||||
|
)
|
|
@ -53,6 +53,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo033
|
||||||
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo034
|
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo034
|
||||||
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo035
|
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo035
|
||||||
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo036
|
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo036
|
||||||
|
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo037
|
||||||
import org.matrix.android.sdk.internal.util.Normalizer
|
import org.matrix.android.sdk.internal.util.Normalizer
|
||||||
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -61,7 +62,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
|
||||||
private val normalizer: Normalizer
|
private val normalizer: Normalizer
|
||||||
) : MatrixRealmMigration(
|
) : MatrixRealmMigration(
|
||||||
dbName = "Session",
|
dbName = "Session",
|
||||||
schemaVersion = 36L,
|
schemaVersion = 37L,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Forces all RealmSessionStoreMigration instances to be equal.
|
* Forces all RealmSessionStoreMigration instances to be equal.
|
||||||
|
@ -107,5 +108,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
|
||||||
if (oldVersion < 34) MigrateSessionTo034(realm).perform()
|
if (oldVersion < 34) MigrateSessionTo034(realm).perform()
|
||||||
if (oldVersion < 35) MigrateSessionTo035(realm).perform()
|
if (oldVersion < 35) MigrateSessionTo035(realm).perform()
|
||||||
if (oldVersion < 36) MigrateSessionTo036(realm).perform()
|
if (oldVersion < 36) MigrateSessionTo036(realm).perform()
|
||||||
|
if (oldVersion < 37) MigrateSessionTo037(realm).perform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.internal.database.mapper
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal class LocalRoomSummaryMapper @Inject constructor(
|
||||||
|
private val roomSummaryMapper: RoomSummaryMapper,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun map(localRoomSummaryEntity: LocalRoomSummaryEntity): LocalRoomSummary {
|
||||||
|
return LocalRoomSummary(
|
||||||
|
roomId = localRoomSummaryEntity.roomId,
|
||||||
|
roomSummary = localRoomSummaryEntity.roomSummaryEntity?.let { roomSummaryMapper.map(it) },
|
||||||
|
createRoomParams = localRoomSummaryEntity.createRoomParams,
|
||||||
|
replacementRoomId = localRoomSummaryEntity.replacementRoomId,
|
||||||
|
creationState = localRoomSummaryEntity.creationState
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.internal.database.migration
|
||||||
|
|
||||||
|
import io.realm.DynamicRealm
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomCreationState
|
||||||
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.util.database.RealmMigrator
|
||||||
|
|
||||||
|
internal class MigrateSessionTo037(realm: DynamicRealm) : RealmMigrator(realm, 37) {
|
||||||
|
|
||||||
|
override fun doMigrate(realm: DynamicRealm) {
|
||||||
|
realm.schema.get("LocalRoomSummaryEntity")
|
||||||
|
?.addField(LocalRoomSummaryEntityFields.REPLACEMENT_ROOM_ID, String::class.java)
|
||||||
|
?.addField(LocalRoomSummaryEntityFields.STATE_STR, String::class.java)
|
||||||
|
?.transform { obj ->
|
||||||
|
obj.set(LocalRoomSummaryEntityFields.STATE_STR, LocalRoomCreationState.NOT_CREATED.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,15 +18,24 @@ package org.matrix.android.sdk.internal.database.model
|
||||||
|
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.annotations.PrimaryKey
|
import io.realm.annotations.PrimaryKey
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomCreationState
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.toJSONString
|
import org.matrix.android.sdk.api.session.room.model.create.toJSONString
|
||||||
|
|
||||||
internal open class LocalRoomSummaryEntity(
|
internal open class LocalRoomSummaryEntity(
|
||||||
@PrimaryKey var roomId: String = "",
|
@PrimaryKey var roomId: String = "",
|
||||||
var roomSummaryEntity: RoomSummaryEntity? = null,
|
var roomSummaryEntity: RoomSummaryEntity? = null,
|
||||||
private var createRoomParamsStr: String? = null
|
var replacementRoomId: String? = null,
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
|
private var stateStr: String = LocalRoomCreationState.NOT_CREATED.name
|
||||||
|
var creationState: LocalRoomCreationState
|
||||||
|
get() = LocalRoomCreationState.valueOf(stateStr)
|
||||||
|
set(value) {
|
||||||
|
stateStr = value.name
|
||||||
|
}
|
||||||
|
|
||||||
|
private var createRoomParamsStr: String? = null
|
||||||
var createRoomParams: CreateRoomParams?
|
var createRoomParams: CreateRoomParams?
|
||||||
get() {
|
get() {
|
||||||
return CreateRoomParams.fromJson(createRoomParamsStr)
|
return CreateRoomParams.fromJson(createRoomParamsStr)
|
||||||
|
|
|
@ -22,10 +22,6 @@ import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
||||||
|
|
||||||
internal fun LocalRoomSummaryEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery<LocalRoomSummaryEntity> {
|
internal fun LocalRoomSummaryEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<LocalRoomSummaryEntity> {
|
||||||
val query = realm.where<LocalRoomSummaryEntity>()
|
return realm.where<LocalRoomSummaryEntity>().equalTo(LocalRoomSummaryEntityFields.ROOM_ID, roomId)
|
||||||
if (roomId != null) {
|
|
||||||
query.equalTo(LocalRoomSummaryEntityFields.ROOM_ID, roomId)
|
|
||||||
}
|
|
||||||
return query
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ internal fun ReadReceiptEntity.Companion.whereUserId(realm: Realm, userId: Strin
|
||||||
.equalTo(ReadReceiptEntityFields.USER_ID, userId)
|
.equalTo(ReadReceiptEntityFields.USER_ID, userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun ReadReceiptEntity.Companion.whereRoomId(realm: Realm, roomId: String): RealmQuery<ReadReceiptEntity> {
|
||||||
|
return realm.where<ReadReceiptEntity>()
|
||||||
|
.equalTo(ReadReceiptEntityFields.ROOM_ID, roomId)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun ReadReceiptEntity.Companion.createUnmanaged(roomId: String, eventId: String, userId: String, originServerTs: Double): ReadReceiptEntity {
|
internal fun ReadReceiptEntity.Companion.createUnmanaged(roomId: String, eventId: String, userId: String, originServerTs: Double): ReadReceiptEntity {
|
||||||
return ReadReceiptEntity().apply {
|
return ReadReceiptEntity().apply {
|
||||||
this.primaryKey = "${roomId}_$userId"
|
this.primaryKey = "${roomId}_$userId"
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.room.call.RoomCallService
|
||||||
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
|
||||||
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
|
import org.matrix.android.sdk.api.session.room.location.LocationSharingService
|
||||||
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationService
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationService
|
||||||
|
@ -82,6 +83,14 @@ internal class DefaultRoom(
|
||||||
return roomSummaryDataSource.getRoomSummary(roomId)
|
return roomSummaryDataSource.getRoomSummary(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getLocalRoomSummaryLive(): LiveData<Optional<LocalRoomSummary>> {
|
||||||
|
return roomSummaryDataSource.getLocalRoomSummaryLive(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun localRoomSummary(): LocalRoomSummary? {
|
||||||
|
return roomSummaryDataSource.getLocalRoomSummary(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun asSpace(): Space? {
|
override fun asSpace(): Space? {
|
||||||
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
if (roomSummary()?.roomType != RoomType.SPACE) return null
|
||||||
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder)
|
||||||
|
|
|
@ -29,10 +29,12 @@ import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
|
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
|
||||||
import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription
|
import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||||
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
|
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
|
import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
|
||||||
|
@ -106,6 +108,10 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
return roomSummaryDataSource.getRoomSummaryLive(roomId)
|
return roomSummaryDataSource.getRoomSummaryLive(roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getLocalRoomSummaryLive(roomId: String): LiveData<Optional<LocalRoomSummary>> {
|
||||||
|
return roomSummaryDataSource.getLocalRoomSummaryLive(roomId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getRoomSummaries(
|
override fun getRoomSummaries(
|
||||||
queryParams: RoomSummaryQueryParams,
|
queryParams: RoomSummaryQueryParams,
|
||||||
sortOrder: RoomSortOrder
|
sortOrder: RoomSortOrder
|
||||||
|
@ -173,8 +179,11 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun onRoomDisplayed(roomId: String) {
|
override suspend fun onRoomDisplayed(roomId: String) {
|
||||||
|
// Do not add local rooms to the recent rooms list as they should not be known by the server
|
||||||
|
if (!RoomLocalEcho.isLocalEchoId(roomId)) {
|
||||||
updateBreadcrumbsTask.execute(UpdateBreadcrumbsTask.Params(roomId))
|
updateBreadcrumbsTask.execute(UpdateBreadcrumbsTask.Params(roomId))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun joinRoom(roomIdOrAlias: String, reason: String?, viaServers: List<String>) {
|
override suspend fun joinRoom(roomIdOrAlias: String, reason: String?, viaServers: List<String>) {
|
||||||
joinRoomTask.execute(JoinRoomTask.Params(roomIdOrAlias, reason, viaServers))
|
joinRoomTask.execute(JoinRoomTask.Params(roomIdOrAlias, reason, viaServers))
|
||||||
|
|
|
@ -17,38 +17,23 @@
|
||||||
package org.matrix.android.sdk.internal.session.room.create
|
package org.matrix.android.sdk.internal.session.room.create
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import io.realm.kotlin.where
|
|
||||||
import kotlinx.coroutines.TimeoutCancellationException
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
|
||||||
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomCreationState
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
|
|
||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
|
||||||
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
||||||
import org.matrix.android.sdk.internal.database.mapper.toEntity
|
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
|
||||||
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
|
||||||
import org.matrix.android.sdk.internal.task.Task
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
|
||||||
import org.matrix.android.sdk.internal.util.time.Clock
|
|
||||||
import java.util.UUID
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -56,94 +41,100 @@ import javax.inject.Inject
|
||||||
* Create a room on the server from a local room.
|
* Create a room on the server from a local room.
|
||||||
* The configuration of the local room will be use to configure the new room.
|
* The configuration of the local room will be use to configure the new room.
|
||||||
* The potential local room members will also be invited to this new room.
|
* The potential local room members will also be invited to this new room.
|
||||||
*
|
|
||||||
* A local tombstone event will be created to indicate that the local room has been replacing by the new one.
|
|
||||||
*/
|
*/
|
||||||
internal interface CreateRoomFromLocalRoomTask : Task<CreateRoomFromLocalRoomTask.Params, String> {
|
internal interface CreateRoomFromLocalRoomTask : Task<CreateRoomFromLocalRoomTask.Params, String> {
|
||||||
data class Params(val localRoomId: String)
|
data class Params(val localRoomId: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DefaultCreateRoomFromLocalRoomTask @Inject constructor(
|
internal class DefaultCreateRoomFromLocalRoomTask @Inject constructor(
|
||||||
@UserId private val userId: String,
|
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val createRoomTask: CreateRoomTask,
|
private val createRoomTask: CreateRoomTask,
|
||||||
private val stateEventDataSource: StateEventDataSource,
|
private val roomSummaryDataSource: RoomSummaryDataSource,
|
||||||
private val clock: Clock,
|
|
||||||
) : CreateRoomFromLocalRoomTask {
|
) : CreateRoomFromLocalRoomTask {
|
||||||
|
|
||||||
private val realmConfiguration
|
private val realmConfiguration
|
||||||
get() = monarchy.realmConfiguration
|
get() = monarchy.realmConfiguration
|
||||||
|
|
||||||
override suspend fun execute(params: CreateRoomFromLocalRoomTask.Params): String {
|
override suspend fun execute(params: CreateRoomFromLocalRoomTask.Params): String {
|
||||||
val replacementRoomId = stateEventDataSource.getStateEvent(params.localRoomId, EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)
|
val localRoomSummary = roomSummaryDataSource.getLocalRoomSummary(params.localRoomId)
|
||||||
?.content.toModel<RoomTombstoneContent>()
|
?: error("## CreateRoomFromLocalRoomTask - Cannot retrieve LocalRoomSummary with roomId ${params.localRoomId}")
|
||||||
?.replacementRoomId
|
|
||||||
|
|
||||||
if (replacementRoomId != null) {
|
// If a room has already been created for the given local room, return the existing roomId
|
||||||
|
if (localRoomSummary.replacementRoomId != null) {
|
||||||
|
return localRoomSummary.replacementRoomId
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localRoomSummary.createRoomParams != null && localRoomSummary.roomSummary != null) {
|
||||||
|
return createRoom(params.localRoomId, localRoomSummary.roomSummary, localRoomSummary.createRoomParams)
|
||||||
|
} else {
|
||||||
|
error("## CreateRoomFromLocalRoomTask - Invalid LocalRoomSummary: $localRoomSummary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a room on the server for the given local room.
|
||||||
|
*
|
||||||
|
* @param localRoomId the local room identifier.
|
||||||
|
* @param localRoomSummary the RoomSummary of the local room.
|
||||||
|
* @param createRoomParams the CreateRoomParams object which was used to configure the local room.
|
||||||
|
*
|
||||||
|
* @return the identifier of the created room.
|
||||||
|
*/
|
||||||
|
private suspend fun createRoom(localRoomId: String, localRoomSummary: RoomSummary, createRoomParams: CreateRoomParams): String {
|
||||||
|
updateCreationState(localRoomId, LocalRoomCreationState.CREATING)
|
||||||
|
val replacementRoomId = runCatching {
|
||||||
|
createRoomTask.execute(createRoomParams)
|
||||||
|
}.fold(
|
||||||
|
{ it },
|
||||||
|
{
|
||||||
|
updateCreationState(localRoomId, LocalRoomCreationState.FAILURE)
|
||||||
|
throw it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
updateReplacementRoomId(localRoomId, replacementRoomId)
|
||||||
|
waitForRoomEvents(replacementRoomId, localRoomSummary)
|
||||||
|
updateCreationState(localRoomId, LocalRoomCreationState.CREATED)
|
||||||
return replacementRoomId
|
return replacementRoomId
|
||||||
}
|
}
|
||||||
|
|
||||||
var createRoomParams: CreateRoomParams? = null
|
/**
|
||||||
var isEncrypted = false
|
* Wait for all the room events before triggering the created state.
|
||||||
monarchy.doWithRealm { realm ->
|
*
|
||||||
realm.where<LocalRoomSummaryEntity>()
|
* @param replacementRoomId the identifier of the created room
|
||||||
.equalTo(LocalRoomSummaryEntityFields.ROOM_ID, params.localRoomId)
|
* @param localRoomSummary the RoomSummary of the local room.
|
||||||
.findFirst()
|
*/
|
||||||
?.let {
|
private suspend fun waitForRoomEvents(replacementRoomId: String, localRoomSummary: RoomSummary) {
|
||||||
createRoomParams = it.createRoomParams
|
|
||||||
isEncrypted = it.roomSummaryEntity?.isEncrypted.orFalse()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val roomId = createRoomTask.execute(createRoomParams!!)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Wait for all the room events before triggering the replacement room
|
|
||||||
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||||
realm.where(RoomSummaryEntity::class.java)
|
realm.where(RoomSummaryEntity::class.java)
|
||||||
.equalTo(RoomSummaryEntityFields.ROOM_ID, roomId)
|
.equalTo(RoomSummaryEntityFields.ROOM_ID, replacementRoomId)
|
||||||
.equalTo(RoomSummaryEntityFields.INVITED_MEMBERS_COUNT, createRoomParams?.invitedUserIds?.size ?: 0)
|
.equalTo(RoomSummaryEntityFields.INVITED_MEMBERS_COUNT, localRoomSummary.invitedMembersCount)
|
||||||
}
|
}
|
||||||
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||||
EventEntity.whereRoomId(realm, roomId)
|
EventEntity.whereRoomId(realm, replacementRoomId)
|
||||||
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_HISTORY_VISIBILITY)
|
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_HISTORY_VISIBILITY)
|
||||||
}
|
}
|
||||||
if (isEncrypted) {
|
if (localRoomSummary.isEncrypted) {
|
||||||
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||||
EventEntity.whereRoomId(realm, roomId)
|
EventEntity.whereRoomId(realm, replacementRoomId)
|
||||||
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_ENCRYPTION)
|
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_ENCRYPTION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (exception: TimeoutCancellationException) {
|
} catch (exception: TimeoutCancellationException) {
|
||||||
throw CreateRoomFailure.CreatedWithTimeout(roomId)
|
updateCreationState(localRoomSummary.roomId, LocalRoomCreationState.FAILURE)
|
||||||
|
throw CreateRoomFailure.CreatedWithTimeout(replacementRoomId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createTombstoneEvent(params, roomId)
|
private fun updateCreationState(roomId: String, creationState: LocalRoomCreationState) {
|
||||||
return roomId
|
monarchy.runTransactionSync { realm ->
|
||||||
|
LocalRoomSummaryEntity.where(realm, roomId).findFirst()?.creationState = creationState
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun updateReplacementRoomId(localRoomId: String, replacementRoomId: String) {
|
||||||
* Create a Tombstone event to indicate that the local room has been replaced by a new one.
|
monarchy.runTransactionSync { realm ->
|
||||||
*/
|
LocalRoomSummaryEntity.where(realm, localRoomId).findFirst()?.replacementRoomId = replacementRoomId
|
||||||
private suspend fun createTombstoneEvent(params: CreateRoomFromLocalRoomTask.Params, roomId: String) {
|
|
||||||
val now = clock.epochMillis()
|
|
||||||
val event = Event(
|
|
||||||
type = EventType.STATE_ROOM_TOMBSTONE,
|
|
||||||
senderId = userId,
|
|
||||||
originServerTs = now,
|
|
||||||
stateKey = "",
|
|
||||||
eventId = UUID.randomUUID().toString(),
|
|
||||||
content = RoomTombstoneContent(
|
|
||||||
replacementRoomId = roomId
|
|
||||||
).toContent()
|
|
||||||
)
|
|
||||||
monarchy.awaitTransaction { realm ->
|
|
||||||
val eventEntity = event.toEntity(params.localRoomId, SendState.SYNCED, now).copyToRealmOrIgnore(realm, EventInsertType.INCREMENTAL_SYNC)
|
|
||||||
if (event.stateKey != null && event.type != null && event.eventId != null) {
|
|
||||||
CurrentStateEventEntity.getOrCreate(realm, params.localRoomId, event.stateKey, event.type).apply {
|
|
||||||
eventId = event.eventId
|
|
||||||
root = eventEntity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,15 @@ import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
|
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
|
import org.matrix.android.sdk.internal.database.query.whereInRoom
|
||||||
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.session.room.delete.DeleteLocalRoomTask.Params
|
import org.matrix.android.sdk.internal.session.room.delete.DeleteLocalRoomTask.Params
|
||||||
|
@ -50,6 +53,12 @@ internal class DefaultDeleteLocalRoomTask @Inject constructor(
|
||||||
if (RoomLocalEcho.isLocalEchoId(roomId)) {
|
if (RoomLocalEcho.isLocalEchoId(roomId)) {
|
||||||
monarchy.awaitTransaction { realm ->
|
monarchy.awaitTransaction { realm ->
|
||||||
Timber.i("## DeleteLocalRoomTask - delete local room id $roomId")
|
Timber.i("## DeleteLocalRoomTask - delete local room id $roomId")
|
||||||
|
ReadReceiptsSummaryEntity.whereInRoom(realm, roomId = roomId).findAll()
|
||||||
|
?.also { Timber.i("## DeleteLocalRoomTask - ReadReceiptsSummaryEntity - delete ${it.size} entries") }
|
||||||
|
?.deleteAllFromRealm()
|
||||||
|
ReadReceiptEntity.whereRoomId(realm, roomId = roomId).findAll()
|
||||||
|
?.also { Timber.i("## DeleteLocalRoomTask - ReadReceiptEntity - delete ${it.size} entries") }
|
||||||
|
?.deleteAllFromRealm()
|
||||||
RoomMemberSummaryEntity.where(realm, roomId = roomId).findAll()
|
RoomMemberSummaryEntity.where(realm, roomId = roomId).findAll()
|
||||||
?.also { Timber.i("## DeleteLocalRoomTask - RoomMemberSummaryEntity - delete ${it.size} entries") }
|
?.also { Timber.i("## DeleteLocalRoomTask - RoomMemberSummaryEntity - delete ${it.size} entries") }
|
||||||
?.deleteAllFromRealm()
|
?.deleteAllFromRealm()
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.room.ResultBoundaries
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
|
import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||||
|
@ -43,7 +44,9 @@ import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotification
|
||||||
import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams
|
import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
import org.matrix.android.sdk.api.util.toOptional
|
||||||
|
import org.matrix.android.sdk.internal.database.mapper.LocalRoomSummaryMapper
|
||||||
import org.matrix.android.sdk.internal.database.mapper.RoomSummaryMapper
|
import org.matrix.android.sdk.internal.database.mapper.RoomSummaryMapper
|
||||||
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.findByAlias
|
import org.matrix.android.sdk.internal.database.query.findByAlias
|
||||||
|
@ -57,6 +60,7 @@ import javax.inject.Inject
|
||||||
internal class RoomSummaryDataSource @Inject constructor(
|
internal class RoomSummaryDataSource @Inject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val roomSummaryMapper: RoomSummaryMapper,
|
private val roomSummaryMapper: RoomSummaryMapper,
|
||||||
|
private val localRoomSummaryMapper: LocalRoomSummaryMapper,
|
||||||
private val queryStringValueProcessor: QueryStringValueProcessor,
|
private val queryStringValueProcessor: QueryStringValueProcessor,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -95,6 +99,25 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLocalRoomSummary(roomId: String): LocalRoomSummary? {
|
||||||
|
return monarchy
|
||||||
|
.fetchCopyMap({
|
||||||
|
LocalRoomSummaryEntity.where(it, roomId).findFirst()
|
||||||
|
}, { entity, _ ->
|
||||||
|
localRoomSummaryMapper.map(entity)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalRoomSummaryLive(roomId: String): LiveData<Optional<LocalRoomSummary>> {
|
||||||
|
val liveData = monarchy.findAllMappedWithChanges(
|
||||||
|
{ realm -> LocalRoomSummaryEntity.where(realm, roomId) },
|
||||||
|
{ localRoomSummaryMapper.map(it) }
|
||||||
|
)
|
||||||
|
return Transformations.map(liveData) { results ->
|
||||||
|
results.firstOrNull().toOptional()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getRoomSummariesLive(
|
fun getRoomSummariesLive(
|
||||||
queryParams: RoomSummaryQueryParams,
|
queryParams: RoomSummaryQueryParams,
|
||||||
sortOrder: RoomSortOrder = RoomSortOrder.NONE
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE
|
||||||
|
|
|
@ -22,21 +22,22 @@ import io.mockk.coVerify
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.spyk
|
||||||
import io.mockk.unmockkAll
|
import io.mockk.unmockkAll
|
||||||
|
import io.mockk.verify
|
||||||
|
import io.mockk.verifyOrder
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.amshove.kluent.shouldBeEqualTo
|
import org.amshove.kluent.shouldBeEqualTo
|
||||||
|
import org.amshove.kluent.shouldBeNull
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomCreationState
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
|
|
||||||
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
|
@ -44,29 +45,24 @@ import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.LocalRoomSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
||||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.util.time.DefaultClock
|
|
||||||
import org.matrix.android.sdk.test.fakes.FakeMonarchy
|
import org.matrix.android.sdk.test.fakes.FakeMonarchy
|
||||||
import org.matrix.android.sdk.test.fakes.FakeStateEventDataSource
|
import org.matrix.android.sdk.test.fakes.FakeRoomSummaryDataSource
|
||||||
|
|
||||||
private const val A_LOCAL_ROOM_ID = "local.a-local-room-id"
|
private const val A_LOCAL_ROOM_ID = "local.a-local-room-id"
|
||||||
private const val AN_EXISTING_ROOM_ID = "an-existing-room-id"
|
private const val AN_EXISTING_ROOM_ID = "an-existing-room-id"
|
||||||
private const val A_ROOM_ID = "a-room-id"
|
private const val A_ROOM_ID = "a-room-id"
|
||||||
private const val MY_USER_ID = "my-user-id"
|
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
internal class DefaultCreateRoomFromLocalRoomTaskTest {
|
internal class DefaultCreateRoomFromLocalRoomTaskTest {
|
||||||
|
|
||||||
private val fakeMonarchy = FakeMonarchy()
|
private val fakeMonarchy = FakeMonarchy()
|
||||||
private val clock = DefaultClock()
|
|
||||||
private val createRoomTask = mockk<CreateRoomTask>()
|
private val createRoomTask = mockk<CreateRoomTask>()
|
||||||
private val fakeStateEventDataSource = FakeStateEventDataSource()
|
private val fakeRoomSummaryDataSource = FakeRoomSummaryDataSource()
|
||||||
|
|
||||||
private val defaultCreateRoomFromLocalRoomTask = DefaultCreateRoomFromLocalRoomTask(
|
private val defaultCreateRoomFromLocalRoomTask = DefaultCreateRoomFromLocalRoomTask(
|
||||||
userId = MY_USER_ID,
|
|
||||||
monarchy = fakeMonarchy.instance,
|
monarchy = fakeMonarchy.instance,
|
||||||
createRoomTask = createRoomTask,
|
createRoomTask = createRoomTask,
|
||||||
stateEventDataSource = fakeStateEventDataSource.instance,
|
roomSummaryDataSource = fakeRoomSummaryDataSource.instance,
|
||||||
clock = clock
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -91,13 +87,12 @@ internal class DefaultCreateRoomFromLocalRoomTaskTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given a local room id when execute then the existing room id is kept`() = runTest {
|
fun `given a local room id when execute then the existing room id is kept`() = runTest {
|
||||||
// Given
|
// Given
|
||||||
givenATombstoneEvent(
|
val aCreateRoomParams = mockk<CreateRoomParams>(relaxed = true)
|
||||||
Event(
|
givenALocalRoomSummary(aCreateRoomParams = aCreateRoomParams, aCreationState = LocalRoomCreationState.CREATED, aReplacementRoomId = AN_EXISTING_ROOM_ID)
|
||||||
roomId = A_LOCAL_ROOM_ID,
|
val aLocalRoomSummaryEntity = givenALocalRoomSummaryEntity(
|
||||||
type = EventType.STATE_ROOM_TOMBSTONE,
|
aCreateRoomParams = aCreateRoomParams,
|
||||||
stateKey = "",
|
aCreationState = LocalRoomCreationState.CREATED,
|
||||||
content = RoomTombstoneContent(replacementRoomId = AN_EXISTING_ROOM_ID).toContent()
|
aReplacementRoomId = AN_EXISTING_ROOM_ID
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// When
|
// When
|
||||||
|
@ -105,20 +100,18 @@ internal class DefaultCreateRoomFromLocalRoomTaskTest {
|
||||||
val result = defaultCreateRoomFromLocalRoomTask.execute(params)
|
val result = defaultCreateRoomFromLocalRoomTask.execute(params)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verifyTombstoneEvent(AN_EXISTING_ROOM_ID)
|
fakeRoomSummaryDataSource.verifyGetLocalRoomSummary(A_LOCAL_ROOM_ID)
|
||||||
result shouldBeEqualTo AN_EXISTING_ROOM_ID
|
result shouldBeEqualTo AN_EXISTING_ROOM_ID
|
||||||
|
aLocalRoomSummaryEntity.replacementRoomId shouldBeEqualTo AN_EXISTING_ROOM_ID
|
||||||
|
aLocalRoomSummaryEntity.creationState shouldBeEqualTo LocalRoomCreationState.CREATED
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a local room id when execute then it is correctly executed`() = runTest {
|
fun `given a local room id when execute then it is correctly executed`() = runTest {
|
||||||
// Given
|
// Given
|
||||||
val aCreateRoomParams = mockk<CreateRoomParams>()
|
val aCreateRoomParams = mockk<CreateRoomParams>(relaxed = true)
|
||||||
val aLocalRoomSummaryEntity = mockk<LocalRoomSummaryEntity> {
|
givenALocalRoomSummary(aCreateRoomParams = aCreateRoomParams, aReplacementRoomId = null)
|
||||||
every { roomSummaryEntity } returns mockk(relaxed = true)
|
val aLocalRoomSummaryEntity = givenALocalRoomSummaryEntity(aCreateRoomParams = aCreateRoomParams, aReplacementRoomId = null)
|
||||||
every { createRoomParams } returns aCreateRoomParams
|
|
||||||
}
|
|
||||||
givenATombstoneEvent(null)
|
|
||||||
givenALocalRoomSummaryEntity(aLocalRoomSummaryEntity)
|
|
||||||
|
|
||||||
coEvery { createRoomTask.execute(any()) } returns A_ROOM_ID
|
coEvery { createRoomTask.execute(any()) } returns A_ROOM_ID
|
||||||
|
|
||||||
|
@ -127,32 +120,84 @@ internal class DefaultCreateRoomFromLocalRoomTaskTest {
|
||||||
val result = defaultCreateRoomFromLocalRoomTask.execute(params)
|
val result = defaultCreateRoomFromLocalRoomTask.execute(params)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
verifyTombstoneEvent(null)
|
fakeRoomSummaryDataSource.verifyGetLocalRoomSummary(A_LOCAL_ROOM_ID)
|
||||||
// CreateRoomTask has been called with the initial CreateRoomParams
|
// CreateRoomTask has been called with the initial CreateRoomParams
|
||||||
coVerify { createRoomTask.execute(aCreateRoomParams) }
|
coVerify { createRoomTask.execute(aCreateRoomParams) }
|
||||||
// The resulting roomId matches the roomId returned by the createRoomTask
|
// The resulting roomId matches the roomId returned by the createRoomTask
|
||||||
result shouldBeEqualTo A_ROOM_ID
|
result shouldBeEqualTo A_ROOM_ID
|
||||||
// A tombstone state event has been created
|
// The room creation state has correctly been updated
|
||||||
coVerify { CurrentStateEventEntity.getOrCreate(realm = any(), roomId = A_LOCAL_ROOM_ID, stateKey = any(), type = EventType.STATE_ROOM_TOMBSTONE) }
|
verifyOrder {
|
||||||
|
aLocalRoomSummaryEntity.creationState = LocalRoomCreationState.CREATING
|
||||||
|
aLocalRoomSummaryEntity.creationState = LocalRoomCreationState.CREATED
|
||||||
|
}
|
||||||
|
// The local room summary has been updated with the created room id
|
||||||
|
verify { aLocalRoomSummaryEntity.replacementRoomId = A_ROOM_ID }
|
||||||
|
aLocalRoomSummaryEntity.replacementRoomId shouldBeEqualTo A_ROOM_ID
|
||||||
|
aLocalRoomSummaryEntity.creationState shouldBeEqualTo LocalRoomCreationState.CREATED
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenATombstoneEvent(event: Event?) {
|
@Test
|
||||||
fakeStateEventDataSource.givenGetStateEventReturns(event)
|
fun `given a local room id when execute with an exception then the creation state is correctly updated`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aCreateRoomParams = mockk<CreateRoomParams>(relaxed = true)
|
||||||
|
givenALocalRoomSummary(aCreateRoomParams = aCreateRoomParams, aReplacementRoomId = null)
|
||||||
|
val aLocalRoomSummaryEntity = givenALocalRoomSummaryEntity(aCreateRoomParams = aCreateRoomParams, aReplacementRoomId = null)
|
||||||
|
|
||||||
|
coEvery { createRoomTask.execute(any()) }.throws(mockk())
|
||||||
|
|
||||||
|
// When
|
||||||
|
val params = CreateRoomFromLocalRoomTask.Params(A_LOCAL_ROOM_ID)
|
||||||
|
tryOrNull { defaultCreateRoomFromLocalRoomTask.execute(params) }
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeRoomSummaryDataSource.verifyGetLocalRoomSummary(A_LOCAL_ROOM_ID)
|
||||||
|
// CreateRoomTask has been called with the initial CreateRoomParams
|
||||||
|
coVerify { createRoomTask.execute(aCreateRoomParams) }
|
||||||
|
// The room creation state has correctly been updated
|
||||||
|
verifyOrder {
|
||||||
|
aLocalRoomSummaryEntity.creationState = LocalRoomCreationState.CREATING
|
||||||
|
aLocalRoomSummaryEntity.creationState = LocalRoomCreationState.FAILURE
|
||||||
|
}
|
||||||
|
// The local room summary has been updated with the created room id
|
||||||
|
aLocalRoomSummaryEntity.replacementRoomId.shouldBeNull()
|
||||||
|
aLocalRoomSummaryEntity.creationState shouldBeEqualTo LocalRoomCreationState.FAILURE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenALocalRoomSummaryEntity(localRoomSummaryEntity: LocalRoomSummaryEntity) {
|
private fun givenALocalRoomSummary(
|
||||||
|
aCreateRoomParams: CreateRoomParams,
|
||||||
|
aCreationState: LocalRoomCreationState = LocalRoomCreationState.NOT_CREATED,
|
||||||
|
aReplacementRoomId: String? = null
|
||||||
|
): LocalRoomSummary {
|
||||||
|
val aLocalRoomSummary = LocalRoomSummary(
|
||||||
|
roomId = A_LOCAL_ROOM_ID,
|
||||||
|
roomSummary = mockk(relaxed = true),
|
||||||
|
createRoomParams = aCreateRoomParams,
|
||||||
|
creationState = aCreationState,
|
||||||
|
replacementRoomId = aReplacementRoomId,
|
||||||
|
)
|
||||||
|
fakeRoomSummaryDataSource.givenGetLocalRoomSummaryReturns(A_LOCAL_ROOM_ID, aLocalRoomSummary)
|
||||||
|
return aLocalRoomSummary
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenALocalRoomSummaryEntity(
|
||||||
|
aCreateRoomParams: CreateRoomParams,
|
||||||
|
aCreationState: LocalRoomCreationState = LocalRoomCreationState.NOT_CREATED,
|
||||||
|
aReplacementRoomId: String? = null
|
||||||
|
): LocalRoomSummaryEntity {
|
||||||
|
val aLocalRoomSummaryEntity = spyk(LocalRoomSummaryEntity(
|
||||||
|
roomId = A_LOCAL_ROOM_ID,
|
||||||
|
roomSummaryEntity = mockk(relaxed = true),
|
||||||
|
replacementRoomId = aReplacementRoomId,
|
||||||
|
).apply {
|
||||||
|
createRoomParams = aCreateRoomParams
|
||||||
|
creationState = aCreationState
|
||||||
|
})
|
||||||
every {
|
every {
|
||||||
fakeMonarchy.fakeRealm.instance
|
fakeMonarchy.fakeRealm.instance
|
||||||
.where<LocalRoomSummaryEntity>()
|
.where<LocalRoomSummaryEntity>()
|
||||||
.equalTo(LocalRoomSummaryEntityFields.ROOM_ID, A_LOCAL_ROOM_ID)
|
.equalTo(LocalRoomSummaryEntityFields.ROOM_ID, A_LOCAL_ROOM_ID)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
} returns localRoomSummaryEntity
|
} returns aLocalRoomSummaryEntity
|
||||||
}
|
return aLocalRoomSummaryEntity
|
||||||
|
|
||||||
private fun verifyTombstoneEvent(expectedRoomId: String?) {
|
|
||||||
fakeStateEventDataSource.verifyGetStateEvent(A_LOCAL_ROOM_ID, EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)
|
|
||||||
fakeStateEventDataSource.instance.getStateEvent(A_LOCAL_ROOM_ID, EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)
|
|
||||||
?.content.toModel<RoomTombstoneContent>()
|
|
||||||
?.replacementRoomId shouldBeEqualTo expectedRoomId
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,11 @@ internal class FakeMonarchy {
|
||||||
} coAnswers {
|
} coAnswers {
|
||||||
firstArg<Monarchy.RealmBlock>().doWithRealm(fakeRealm.instance)
|
firstArg<Monarchy.RealmBlock>().doWithRealm(fakeRealm.instance)
|
||||||
}
|
}
|
||||||
|
coEvery {
|
||||||
|
instance.runTransactionSync(any())
|
||||||
|
} coAnswers {
|
||||||
|
firstArg<Realm.Transaction>().execute(fakeRealm.instance)
|
||||||
|
}
|
||||||
every { instance.realmConfiguration } returns mockk()
|
every { instance.realmConfiguration } returns mockk()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.test.fakes
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomSummary
|
||||||
|
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource
|
||||||
|
|
||||||
|
internal class FakeRoomSummaryDataSource {
|
||||||
|
|
||||||
|
val instance: RoomSummaryDataSource = mockk()
|
||||||
|
|
||||||
|
fun givenGetLocalRoomSummaryReturns(roomId: String?, localRoomSummary: LocalRoomSummary?) {
|
||||||
|
every { instance.getLocalRoomSummary(roomId = roomId ?: any()) } returns localRoomSummary
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyGetLocalRoomSummary(roomId: String) {
|
||||||
|
verify { instance.getLocalRoomSummary(roomId) }
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -370,9 +370,9 @@ dependencies {
|
||||||
debugImplementation 'com.facebook.soloader:soloader:0.10.4'
|
debugImplementation 'com.facebook.soloader:soloader:0.10.4'
|
||||||
debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.2.0"
|
debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.2.0"
|
||||||
|
|
||||||
gplayImplementation "com.google.android.gms:play-services-location:16.0.0"
|
gplayImplementation "com.google.android.gms:play-services-location:20.0.0"
|
||||||
// UnifiedPush gplay flavor only
|
// UnifiedPush gplay flavor only
|
||||||
gplayImplementation('com.github.UnifiedPush:android-embedded_fcm_distributor:2.1.2') {
|
gplayImplementation('com.google.firebase:firebase-messaging:23.0.8') {
|
||||||
exclude group: 'com.google.firebase', module: 'firebase-core'
|
exclude group: 'com.google.firebase', module: 'firebase-core'
|
||||||
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
||||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||||
|
|
|
@ -225,8 +225,8 @@ class VerifySessionInteractiveTest : VerificationTestBase() {
|
||||||
|
|
||||||
// Wait until local secrets are known (gossip)
|
// Wait until local secrets are known (gossip)
|
||||||
withIdlingResource(allSecretsKnownIdling(uiSession)) {
|
withIdlingResource(allSecretsKnownIdling(uiSession)) {
|
||||||
onView(withId(R.id.groupToolbarAvatarImageView))
|
onView(withId(R.id.roomListContainer))
|
||||||
.perform(click())
|
.check(matches(isDisplayed()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ import im.vector.app.withIdlingResource
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class ElementRobot(
|
class ElementRobot(
|
||||||
private val labsPreferences: LabFeaturesPreferences = LabFeaturesPreferences(false)
|
private val labsPreferences: LabFeaturesPreferences = LabFeaturesPreferences(true)
|
||||||
) {
|
) {
|
||||||
fun onboarding(block: OnboardingRobot.() -> Unit) {
|
fun onboarding(block: OnboardingRobot.() -> Unit) {
|
||||||
block(OnboardingRobot())
|
block(OnboardingRobot())
|
||||||
|
@ -110,9 +110,6 @@ class ElementRobot(
|
||||||
closeSoftKeyboard()
|
closeSoftKeyboard()
|
||||||
block(NewDirectMessageRobot())
|
block(NewDirectMessageRobot())
|
||||||
pressBack()
|
pressBack()
|
||||||
if (labsPreferences.isNewAppLayoutEnabled) {
|
|
||||||
pressBack() // close create dialog
|
|
||||||
}
|
|
||||||
waitUntilViewVisible(withId(R.id.roomListContainer))
|
waitUntilViewVisible(withId(R.id.roomListContainer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,9 +118,6 @@ class ElementRobot(
|
||||||
clickOn(R.id.bottom_action_rooms)
|
clickOn(R.id.bottom_action_rooms)
|
||||||
}
|
}
|
||||||
RoomListRobot(labsPreferences).newRoom { block() }
|
RoomListRobot(labsPreferences).newRoom { block() }
|
||||||
if (labsPreferences.isNewAppLayoutEnabled) {
|
|
||||||
pressBack() // close create dialog
|
|
||||||
}
|
|
||||||
waitUntilViewVisible(withId(R.id.roomListContainer))
|
waitUntilViewVisible(withId(R.id.roomListContainer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,11 +80,6 @@ class DebugFeaturesStateFactory @Inject constructor(
|
||||||
key = DebugFeatureKeys.forceUsageOfOpusEncoder,
|
key = DebugFeatureKeys.forceUsageOfOpusEncoder,
|
||||||
factory = VectorFeatures::forceUsageOfOpusEncoder
|
factory = VectorFeatures::forceUsageOfOpusEncoder
|
||||||
),
|
),
|
||||||
createBooleanFeature(
|
|
||||||
label = "Start DM on first message",
|
|
||||||
key = DebugFeatureKeys.startDmOnFirstMsg,
|
|
||||||
factory = VectorFeatures::shouldStartDmOnFirstMessage
|
|
||||||
),
|
|
||||||
createBooleanFeature(
|
createBooleanFeature(
|
||||||
label = "Enable New App Layout",
|
label = "Enable New App Layout",
|
||||||
key = DebugFeatureKeys.newAppLayoutEnabled,
|
key = DebugFeatureKeys.newAppLayoutEnabled,
|
||||||
|
|
|
@ -73,9 +73,6 @@ class DebugVectorFeatures(
|
||||||
override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
|
override fun forceUsageOfOpusEncoder(): Boolean = read(DebugFeatureKeys.forceUsageOfOpusEncoder)
|
||||||
?: vectorFeatures.forceUsageOfOpusEncoder()
|
?: vectorFeatures.forceUsageOfOpusEncoder()
|
||||||
|
|
||||||
override fun shouldStartDmOnFirstMessage(): Boolean = read(DebugFeatureKeys.startDmOnFirstMsg)
|
|
||||||
?: vectorFeatures.shouldStartDmOnFirstMessage()
|
|
||||||
|
|
||||||
override fun isNewAppLayoutFeatureEnabled(): Boolean = read(DebugFeatureKeys.newAppLayoutEnabled)
|
override fun isNewAppLayoutFeatureEnabled(): Boolean = read(DebugFeatureKeys.newAppLayoutEnabled)
|
||||||
?: vectorFeatures.isNewAppLayoutFeatureEnabled()
|
?: vectorFeatures.isNewAppLayoutFeatureEnabled()
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
<bool name="settings_ignored_users_visible">true</bool>
|
<bool name="settings_ignored_users_visible">true</bool>
|
||||||
|
|
||||||
<!-- Level 1: Labs -->
|
<!-- Level 1: Labs -->
|
||||||
|
<bool name="settings_labs_deferred_dm_visible">true</bool>
|
||||||
|
<bool name="settings_labs_deferred_dm_default">true</bool>
|
||||||
<bool name="settings_labs_thread_messages_default">false</bool>
|
<bool name="settings_labs_thread_messages_default">false</bool>
|
||||||
<bool name="settings_labs_new_app_layout_default">false</bool>
|
<bool name="settings_labs_new_app_layout_default">true</bool>
|
||||||
<bool name="settings_timeline_show_live_sender_info_visible">true</bool>
|
<bool name="settings_timeline_show_live_sender_info_visible">true</bool>
|
||||||
<bool name="settings_timeline_show_live_sender_info_default">false</bool>
|
<bool name="settings_timeline_show_live_sender_info_default">false</bool>
|
||||||
<!-- Level 1: Advanced settings -->
|
<!-- Level 1: Advanced settings -->
|
||||||
|
|
|
@ -323,6 +323,7 @@
|
||||||
<activity android:name=".features.home.room.list.home.invites.InvitesActivity" />
|
<activity android:name=".features.home.room.list.home.invites.InvitesActivity" />
|
||||||
<activity android:name=".features.home.room.list.home.release.ReleaseNotesActivity" />
|
<activity android:name=".features.home.room.list.home.release.ReleaseNotesActivity" />
|
||||||
<activity android:name=".features.settings.devices.v2.overview.SessionOverviewActivity" />
|
<activity android:name=".features.settings.devices.v2.overview.SessionOverviewActivity" />
|
||||||
|
<activity android:name=".features.settings.devices.v2.othersessions.OtherSessionsActivity" />
|
||||||
<activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity" />
|
<activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity" />
|
||||||
|
|
||||||
<!-- Services -->
|
<!-- Services -->
|
||||||
|
|
|
@ -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.DeviceVerificationInfoBottomSheetViewModel
|
||||||
import im.vector.app.features.settings.devices.DevicesViewModel
|
import im.vector.app.features.settings.devices.DevicesViewModel
|
||||||
import im.vector.app.features.settings.devices.v2.details.SessionDetailsViewModel
|
import im.vector.app.features.settings.devices.v2.details.SessionDetailsViewModel
|
||||||
|
import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsViewModel
|
||||||
import im.vector.app.features.settings.devices.v2.overview.SessionOverviewViewModel
|
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.AccountDataViewModel
|
||||||
import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel
|
import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel
|
||||||
|
@ -643,6 +644,11 @@ interface MavericksViewModelModule {
|
||||||
@MavericksViewModelKey(SessionOverviewViewModel::class)
|
@MavericksViewModelKey(SessionOverviewViewModel::class)
|
||||||
fun sessionOverviewViewModelFactory(factory: SessionOverviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
fun sessionOverviewViewModelFactory(factory: SessionOverviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@MavericksViewModelKey(OtherSessionsViewModel::class)
|
||||||
|
fun otherSessionsViewModelFactory(factory: OtherSessionsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@MavericksViewModelKey(SessionDetailsViewModel::class)
|
@MavericksViewModelKey(SessionDetailsViewModel::class)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This observer detects when item was added or moved to the first position of the adapter, while recyclerView is scrolled to the top. This is necessary
|
||||||
|
* to force recycler to scroll to the top to make such item visible, because by default it will keep items on screen, while adding new item to the top,
|
||||||
|
* outside of the viewport
|
||||||
|
* @param layoutManager - [LinearLayoutManager] of the recycler view, which displays items
|
||||||
|
* @property onItemUpdated - callback to be called, when observer detects event
|
||||||
|
*/
|
||||||
|
class FirstItemUpdatedObserver(
|
||||||
|
layoutManager: LinearLayoutManager,
|
||||||
|
private val onItemUpdated: () -> Unit
|
||||||
|
) : RecyclerView.AdapterDataObserver() {
|
||||||
|
|
||||||
|
val layoutManager: LinearLayoutManager? by weak(layoutManager)
|
||||||
|
|
||||||
|
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
|
||||||
|
if ((toPosition == 0 || fromPosition == 0) && layoutManager?.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||||
|
onItemUpdated.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||||
|
if (positionStart == 0 && layoutManager?.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||||
|
onItemUpdated.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,6 @@ interface VectorFeatures {
|
||||||
fun isScreenSharingEnabled(): Boolean
|
fun isScreenSharingEnabled(): Boolean
|
||||||
fun isLocationSharingEnabled(): Boolean
|
fun isLocationSharingEnabled(): Boolean
|
||||||
fun forceUsageOfOpusEncoder(): Boolean
|
fun forceUsageOfOpusEncoder(): Boolean
|
||||||
fun shouldStartDmOnFirstMessage(): Boolean
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is only to enable if the labs flag should be visible and effective.
|
* This is only to enable if the labs flag should be visible and effective.
|
||||||
|
@ -56,7 +55,6 @@ class DefaultVectorFeatures : VectorFeatures {
|
||||||
override fun isScreenSharingEnabled(): Boolean = true
|
override fun isScreenSharingEnabled(): Boolean = true
|
||||||
override fun isLocationSharingEnabled() = Config.ENABLE_LOCATION_SHARING
|
override fun isLocationSharingEnabled() = Config.ENABLE_LOCATION_SHARING
|
||||||
override fun forceUsageOfOpusEncoder(): Boolean = false
|
override fun forceUsageOfOpusEncoder(): Boolean = false
|
||||||
override fun shouldStartDmOnFirstMessage(): Boolean = false
|
|
||||||
override fun isNewAppLayoutFeatureEnabled(): Boolean = true
|
override fun isNewAppLayoutFeatureEnabled(): Boolean = true
|
||||||
override fun isNewDeviceManagementEnabled(): Boolean = false
|
override fun isNewDeviceManagementEnabled(): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.mvrx.runCatchingToAsync
|
import im.vector.app.core.mvrx.runCatchingToAsync
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.VectorFeatures
|
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import im.vector.app.features.raw.wellknown.getElementWellknown
|
import im.vector.app.features.raw.wellknown.getElementWellknown
|
||||||
import im.vector.app.features.raw.wellknown.isE2EByDefault
|
import im.vector.app.features.raw.wellknown.isE2EByDefault
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.userdirectory.PendingSelection
|
import im.vector.app.features.userdirectory.PendingSelection
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -45,9 +45,9 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||||
class CreateDirectRoomViewModel @AssistedInject constructor(
|
class CreateDirectRoomViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: CreateDirectRoomViewState,
|
@Assisted initialState: CreateDirectRoomViewState,
|
||||||
private val rawService: RawService,
|
private val rawService: RawService,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
val session: Session,
|
val session: Session,
|
||||||
val analyticsTracker: AnalyticsTracker,
|
val analyticsTracker: AnalyticsTracker,
|
||||||
val vectorFeatures: VectorFeatures
|
|
||||||
) :
|
) :
|
||||||
VectorViewModel<CreateDirectRoomViewState, CreateDirectRoomAction, CreateDirectRoomViewEvents>(initialState) {
|
VectorViewModel<CreateDirectRoomViewState, CreateDirectRoomAction, CreateDirectRoomViewEvents>(initialState) {
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = runCatchingToAsync {
|
val result = runCatchingToAsync {
|
||||||
if (vectorFeatures.shouldStartDmOnFirstMessage()) {
|
if (vectorPreferences.isDeferredDmEnabled()) {
|
||||||
session.roomService().createLocalRoom(roomParams)
|
session.roomService().createLocalRoom(roomParams)
|
||||||
} else {
|
} else {
|
||||||
analyticsTracker.capture(CreatedRoom(isDM = roomParams.isDirect.orFalse()))
|
analyticsTracker.capture(CreatedRoom(isDM = roomParams.isDirect.orFalse()))
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
package im.vector.app.features.createdirect
|
package im.vector.app.features.createdirect
|
||||||
|
|
||||||
import im.vector.app.features.VectorFeatures
|
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import im.vector.app.features.raw.wellknown.getElementWellknown
|
import im.vector.app.features.raw.wellknown.getElementWellknown
|
||||||
import im.vector.app.features.raw.wellknown.isE2EByDefault
|
import im.vector.app.features.raw.wellknown.isE2EByDefault
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.raw.RawService
|
import org.matrix.android.sdk.api.raw.RawService
|
||||||
|
@ -32,7 +32,7 @@ class DirectRoomHelper @Inject constructor(
|
||||||
private val rawService: RawService,
|
private val rawService: RawService,
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val analyticsTracker: AnalyticsTracker,
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
private val vectorFeatures: VectorFeatures,
|
private val vectorPreferences: VectorPreferences,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun ensureDMExists(userId: String): String {
|
suspend fun ensureDMExists(userId: String): String {
|
||||||
|
@ -50,7 +50,7 @@ class DirectRoomHelper @Inject constructor(
|
||||||
setDirectMessage()
|
setDirectMessage()
|
||||||
enableEncryptionIfInvitedUsersSupportIt = adminE2EByDefault
|
enableEncryptionIfInvitedUsersSupportIt = adminE2EByDefault
|
||||||
}
|
}
|
||||||
roomId = if (vectorFeatures.shouldStartDmOnFirstMessage()) {
|
roomId = if (vectorPreferences.isDeferredDmEnabled()) {
|
||||||
session.roomService().createLocalRoom(roomParams)
|
session.roomService().createLocalRoom(roomParams)
|
||||||
} else {
|
} else {
|
||||||
analyticsTracker.capture(CreatedRoom(isDM = roomParams.isDirect.orFalse()))
|
analyticsTracker.capture(CreatedRoom(isDM = roomParams.isDirect.orFalse()))
|
||||||
|
|
|
@ -84,6 +84,7 @@ import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
||||||
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
|
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
|
||||||
import im.vector.app.features.spaces.share.ShareSpaceBottomSheet
|
import im.vector.app.features.spaces.share.ShareSpaceBottomSheet
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
import im.vector.app.features.usercode.UserCodeActivity
|
||||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
@ -634,10 +635,18 @@ class HomeActivity :
|
||||||
launchInviteFriends()
|
launchInviteFriends()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.menu_home_qr -> {
|
||||||
|
launchQrCode()
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun launchQrCode() {
|
||||||
|
startActivity(UserCodeActivity.newIntent(this, sharedActionViewModel.session.myUserId))
|
||||||
|
}
|
||||||
|
|
||||||
private fun launchInviteFriends() {
|
private fun launchInviteFriends() {
|
||||||
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(sharedActionViewModel.session.myUserId)?.let { permalink ->
|
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(sharedActionViewModel.session.myUserId)?.let { permalink ->
|
||||||
analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.InviteFriends))
|
analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.InviteFriends))
|
||||||
|
|
|
@ -119,8 +119,9 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeReleaseNotes() = withState { state ->
|
private fun observeReleaseNotes() = withState { state ->
|
||||||
|
if (vectorPreferences.isNewAppLayoutEnabled()) {
|
||||||
// we don't want to show release notes for new users or after relogin
|
// we don't want to show release notes for new users or after relogin
|
||||||
if (state.authenticationDescription == null && vectorPreferences.isNewAppLayoutEnabled()) {
|
if (state.authenticationDescription == null) {
|
||||||
releaseNotesPreferencesStore.appLayoutOnboardingShown.onEach { isAppLayoutOnboardingShown ->
|
releaseNotesPreferencesStore.appLayoutOnboardingShown.onEach { isAppLayoutOnboardingShown ->
|
||||||
if (!isAppLayoutOnboardingShown) {
|
if (!isAppLayoutOnboardingShown) {
|
||||||
_viewEvents.post(HomeActivityViewEvents.ShowReleaseNotes)
|
_viewEvents.post(HomeActivityViewEvents.ShowReleaseNotes)
|
||||||
|
@ -133,6 +134,7 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeAnalytics() {
|
private fun observeAnalytics() {
|
||||||
if (analyticsConfig.isEnabled) {
|
if (analyticsConfig.isEnabled) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents {
|
||||||
object OpenRoomProfile : RoomDetailViewEvents()
|
object OpenRoomProfile : RoomDetailViewEvents()
|
||||||
data class ShowRoomAvatarFullScreen(val matrixItem: MatrixItem?, val view: View?) : RoomDetailViewEvents()
|
data class ShowRoomAvatarFullScreen(val matrixItem: MatrixItem?, val view: View?) : RoomDetailViewEvents()
|
||||||
|
|
||||||
object ShowWaitingView : RoomDetailViewEvents()
|
data class ShowWaitingView(val text: String? = null) : RoomDetailViewEvents()
|
||||||
object HideWaitingView : RoomDetailViewEvents()
|
object HideWaitingView : RoomDetailViewEvents()
|
||||||
|
|
||||||
data class DownloadFileState(
|
data class DownloadFileState(
|
||||||
|
|
|
@ -493,7 +493,7 @@ class TimelineFragment :
|
||||||
is RoomDetailViewEvents.ShowInfoOkDialog -> showDialogWithMessage(it.message)
|
is RoomDetailViewEvents.ShowInfoOkDialog -> showDialogWithMessage(it.message)
|
||||||
is RoomDetailViewEvents.JoinJitsiConference -> joinJitsiRoom(it.widget, it.withVideo)
|
is RoomDetailViewEvents.JoinJitsiConference -> joinJitsiRoom(it.widget, it.withVideo)
|
||||||
RoomDetailViewEvents.LeaveJitsiConference -> leaveJitsiConference()
|
RoomDetailViewEvents.LeaveJitsiConference -> leaveJitsiConference()
|
||||||
RoomDetailViewEvents.ShowWaitingView -> vectorBaseActivity.showWaitingView()
|
is RoomDetailViewEvents.ShowWaitingView -> vectorBaseActivity.showWaitingView(it.text)
|
||||||
RoomDetailViewEvents.HideWaitingView -> vectorBaseActivity.hideWaitingView()
|
RoomDetailViewEvents.HideWaitingView -> vectorBaseActivity.hideWaitingView()
|
||||||
is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it)
|
is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it)
|
||||||
is RoomDetailViewEvents.OpenRoom -> handleOpenRoom(it)
|
is RoomDetailViewEvents.OpenRoom -> handleOpenRoom(it)
|
||||||
|
|
|
@ -39,6 +39,7 @@ import im.vector.app.core.utils.BehaviorDataSource
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.DecryptionFailureTracker
|
import im.vector.app.features.analytics.DecryptionFailureTracker
|
||||||
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
|
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
|
||||||
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||||
import im.vector.app.features.call.conference.ConferenceEvent
|
import im.vector.app.features.call.conference.ConferenceEvent
|
||||||
import im.vector.app.features.call.conference.JitsiActiveConferenceHolder
|
import im.vector.app.features.call.conference.JitsiActiveConferenceHolder
|
||||||
|
@ -78,12 +79,12 @@ import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.raw.RawService
|
import org.matrix.android.sdk.api.raw.RawService
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
||||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||||
|
@ -100,9 +101,11 @@ import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult
|
import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.LocalRoomCreationState
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
|
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
|
import org.matrix.android.sdk.api.session.room.model.tombstone.RoomTombstoneContent
|
||||||
|
@ -185,6 +188,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
init {
|
init {
|
||||||
// This method will take care of a null room to update the state.
|
// This method will take care of a null room to update the state.
|
||||||
observeRoomSummary()
|
observeRoomSummary()
|
||||||
|
observeLocalRoomSummary()
|
||||||
if (room == null) {
|
if (room == null) {
|
||||||
timeline = null
|
timeline = null
|
||||||
} else {
|
} else {
|
||||||
|
@ -617,7 +621,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAddJitsiConference(action: RoomDetailAction.AddJitsiWidget) {
|
private fun handleAddJitsiConference(action: RoomDetailAction.AddJitsiWidget) {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView)
|
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView())
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val widget = jitsiService.createJitsiWidget(initialState.roomId, action.withVideo)
|
val widget = jitsiService.createJitsiWidget(initialState.roomId, action.withVideo)
|
||||||
|
@ -637,7 +641,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
if (isJitsiWidget) {
|
if (isJitsiWidget) {
|
||||||
setState { copy(jitsiState = jitsiState.copy(deleteWidgetInProgress = true)) }
|
setState { copy(jitsiState = jitsiState.copy(deleteWidgetInProgress = true)) }
|
||||||
} else {
|
} else {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView)
|
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView())
|
||||||
}
|
}
|
||||||
session.widgetService().destroyRoomWidget(initialState.roomId, widgetId)
|
session.widgetService().destroyRoomWidget(initialState.roomId, widgetId)
|
||||||
// local echo
|
// local echo
|
||||||
|
@ -1231,6 +1235,32 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun observeLocalRoomSummary() {
|
||||||
|
if (room != null && RoomLocalEcho.isLocalEchoId(room.roomId)) {
|
||||||
|
room.flow().liveLocalRoomSummary()
|
||||||
|
.unwrap()
|
||||||
|
.map { it.creationState }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.onEach { creationState ->
|
||||||
|
when (creationState) {
|
||||||
|
LocalRoomCreationState.NOT_CREATED -> Unit
|
||||||
|
LocalRoomCreationState.CREATING ->
|
||||||
|
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView(stringProvider.getString(R.string.creating_direct_room)))
|
||||||
|
LocalRoomCreationState.FAILURE -> {
|
||||||
|
_viewEvents.post(RoomDetailViewEvents.HideWaitingView)
|
||||||
|
}
|
||||||
|
LocalRoomCreationState.CREATED -> {
|
||||||
|
room.localRoomSummary()?.let {
|
||||||
|
analyticsTracker.capture(CreatedRoom(isDM = it.roomSummary?.isDirect.orFalse()))
|
||||||
|
_viewEvents.post(RoomDetailViewEvents.OpenRoom(it.replacementRoomId!!, true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.launchIn(viewModelScope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getUnreadState() {
|
private fun getUnreadState() {
|
||||||
if (room == null) return
|
if (room == null) return
|
||||||
combine(
|
combine(
|
||||||
|
@ -1322,26 +1352,11 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)?.also {
|
room.getStateEvent(EventType.STATE_ROOM_TOMBSTONE, QueryStringValue.IsEmpty)?.also {
|
||||||
onRoomTombstoneUpdated(it)
|
setState { copy(tombstoneEvent = it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var roomTombstoneHandled = false
|
|
||||||
private fun onRoomTombstoneUpdated(tombstoneEvent: Event) = withState { state ->
|
|
||||||
if (roomTombstoneHandled) return@withState
|
|
||||||
if (state.isLocalRoom()) {
|
|
||||||
// Local room has been replaced, so navigate to the new room
|
|
||||||
val roomId = tombstoneEvent.getClearContent()?.toModel<RoomTombstoneContent>()
|
|
||||||
?.replacementRoomId
|
|
||||||
?: return@withState
|
|
||||||
_viewEvents.post(RoomDetailViewEvents.OpenRoom(roomId, closeCurrentRoom = true))
|
|
||||||
roomTombstoneHandled = true
|
|
||||||
} else {
|
|
||||||
setState { copy(tombstoneEvent = tombstoneEvent) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates to the appropriate event (by paginating the thread timeline until the event is found
|
* Navigates to the appropriate event (by paginating the thread timeline until the event is found
|
||||||
* in the snapshot. The main reason for this function is to support the /relations api
|
* in the snapshot. The main reason for this function is to support the /relations api
|
||||||
|
|
|
@ -31,4 +31,5 @@ sealed class RoomListAction : VectorViewModelAction {
|
||||||
data class LeaveRoom(val roomId: String) : RoomListAction()
|
data class LeaveRoom(val roomId: String) : RoomListAction()
|
||||||
data class JoinSuggestedRoom(val roomId: String, val viaServers: List<String>?) : RoomListAction()
|
data class JoinSuggestedRoom(val roomId: String, val viaServers: List<String>?) : RoomListAction()
|
||||||
data class ShowRoomDetails(val roomId: String, val viaServers: List<String>?) : RoomListAction()
|
data class ShowRoomDetails(val roomId: String, val viaServers: List<String>?) : RoomListAction()
|
||||||
|
object DeleteAllLocalRoom : RoomListAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,10 +149,13 @@ class RoomListFragment :
|
||||||
(it.contentEpoxyController as? RoomSummaryPagedController)?.roomChangeMembershipStates = ms
|
(it.contentEpoxyController as? RoomSummaryPagedController)?.roomChangeMembershipStates = ms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
roomListViewModel.onEach(RoomListViewState::localRoomIds) {
|
|
||||||
// Local rooms should not exist anymore when the room list is shown
|
|
||||||
roomListViewModel.deleteLocalRooms(it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
|
||||||
|
// Local rooms should not exist anymore when the room list is shown
|
||||||
|
roomListViewModel.handle(RoomListAction.DeleteAllLocalRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshCollapseStates() {
|
private fun refreshCollapseStates() {
|
||||||
|
|
|
@ -97,7 +97,6 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
init {
|
init {
|
||||||
observeMembershipChanges()
|
observeMembershipChanges()
|
||||||
observeLocalRooms()
|
|
||||||
|
|
||||||
spaceStateHandler.getSelectedSpaceFlow()
|
spaceStateHandler.getSelectedSpaceFlow()
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
@ -125,16 +124,6 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeLocalRooms() {
|
|
||||||
session
|
|
||||||
.flow()
|
|
||||||
.liveRoomSummaries(roomSummaryQueryParams {
|
|
||||||
roomId = QueryStringValue.Contains(RoomLocalEcho.PREFIX)
|
|
||||||
})
|
|
||||||
.map { page -> page.map { it.roomId } }
|
|
||||||
.setOnEach { copy(localRoomIds = it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> by hiltMavericksViewModelFactory()
|
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
private val roomListSectionBuilder = RoomListSectionBuilder(
|
private val roomListSectionBuilder = RoomListSectionBuilder(
|
||||||
|
@ -166,6 +155,7 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
is RoomListAction.ToggleSection -> handleToggleSection(action.section)
|
is RoomListAction.ToggleSection -> handleToggleSection(action.section)
|
||||||
is RoomListAction.JoinSuggestedRoom -> handleJoinSuggestedRoom(action)
|
is RoomListAction.JoinSuggestedRoom -> handleJoinSuggestedRoom(action)
|
||||||
is RoomListAction.ShowRoomDetails -> handleShowRoomDetails(action)
|
is RoomListAction.ShowRoomDetails -> handleShowRoomDetails(action)
|
||||||
|
RoomListAction.DeleteAllLocalRoom -> handleDeleteLocalRooms()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,14 +163,6 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
|
return session.getRoom(roomId)?.stateService()?.isPublic().orFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteLocalRooms(roomsIds: Iterable<String>) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
roomsIds.forEach {
|
|
||||||
session.roomService().deleteLocalRoom(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRIVATE METHODS *****************************************************************************
|
// PRIVATE METHODS *****************************************************************************
|
||||||
|
|
||||||
private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState {
|
private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState {
|
||||||
|
@ -338,4 +320,16 @@ class RoomListViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(value)
|
_viewEvents.post(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleDeleteLocalRooms() {
|
||||||
|
val localRoomIds = session.roomService()
|
||||||
|
.getRoomSummaries(roomSummaryQueryParams { roomId = QueryStringValue.Contains(RoomLocalEcho.PREFIX) })
|
||||||
|
.map { it.roomId }
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
localRoomIds.forEach {
|
||||||
|
session.roomService().deleteLocalRoom(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ data class RoomListViewState(
|
||||||
val asyncSuggestedRooms: Async<List<SpaceChildInfo>> = Uninitialized,
|
val asyncSuggestedRooms: Async<List<SpaceChildInfo>> = Uninitialized,
|
||||||
val currentUserName: String? = null,
|
val currentUserName: String? = null,
|
||||||
val asyncSelectedSpace: Async<RoomSummary?> = Uninitialized,
|
val asyncSelectedSpace: Async<RoomSummary?> = Uninitialized,
|
||||||
val localRoomIds: List<String> = emptyList()
|
|
||||||
) : MavericksState {
|
) : MavericksState {
|
||||||
|
|
||||||
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
||||||
|
|
|
@ -103,6 +103,9 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>(R.layo
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var showSelected: Boolean = false
|
var showSelected: Boolean = false
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var useSingleLineForLastEvent: Boolean = false
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
|
|
||||||
|
@ -122,6 +125,10 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>(R.layo
|
||||||
holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending
|
holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending
|
||||||
renderSelection(holder, showSelected)
|
renderSelection(holder, showSelected)
|
||||||
holder.roomAvatarPresenceImageView.render(showPresence, userPresence)
|
holder.roomAvatarPresenceImageView.render(showPresence, userPresence)
|
||||||
|
|
||||||
|
if (useSingleLineForLastEvent) {
|
||||||
|
holder.subtitleView.setLines(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderDisplayMode(holder: Holder) = when (displayMode) {
|
private fun renderDisplayMode(holder: Holder) = when (displayMode) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue