diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 4901a84070..91352bb27b 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -11,7 +11,7 @@ jobs:
- run: |
npm install --save-dev @babel/plugin-transform-flow-strip-types
- name: Danger
- uses: danger/danger-js@11.2.1
+ uses: danger/danger-js@11.2.2
with:
args: "--dangerfile ./tools/danger/dangerfile.js"
env:
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
index c32cb65c42..e8c56ba67f 100644
--- a/.github/workflows/quality.yml
+++ b/.github/workflows/quality.yml
@@ -66,7 +66,7 @@ jobs:
yarn add danger-plugin-lint-report --dev
- name: Danger lint
if: always()
- uses: danger/danger-js@11.2.1
+ uses: danger/danger-js@11.2.2
with:
args: "--dangerfile ./tools/danger/dangerfile-lint.js"
env:
diff --git a/CHANGES.md b/CHANGES.md
index 15b0a76b23..76b46bbbe7 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,43 @@
+Changes in Element v1.5.22 (2023-01-25)
+=======================================
+
+Features ✨
+----------
+ - [Poll] Warning message on decryption failure of some events ([#7824](https://github.com/vector-im/element-android/issues/7824))
+ - [Poll] Render ended polls ([#7900](https://github.com/vector-im/element-android/issues/7900))
+ - [Rich text editor] Update list item bullet appearance ([#7930](https://github.com/vector-im/element-android/issues/7930))
+ - [Voice Broadcast] Handle connection errors while recording ([#7890](https://github.com/vector-im/element-android/issues/7890))
+ - [Voice Broadcast] Use MSC3912 to delete server side all the related events ([#7967](https://github.com/vector-im/element-android/issues/7967))
+
+Bugfixes 🐛
+----------
+- Fix OOM crashes. ([#7962](https://github.com/vector-im/element-android/issues/7962))
+- Fix can't get out of a verification dialog ([#4025](https://github.com/vector-im/element-android/issues/4025))
+- Fix rendering of edited polls ([#7938](https://github.com/vector-im/element-android/issues/7938))
+- [Voice Broadcast] Fix unexpected "live broadcast" in the room list ([#7832](https://github.com/vector-im/element-android/issues/7832))
+- Send voice message should not be allowed during a voice broadcast recording ([#7895](https://github.com/vector-im/element-android/issues/7895))
+- Voice Broadcast - Fix playback scrubbing not working if the playback is in a stopped state ([#7961](https://github.com/vector-im/element-android/issues/7961))
+- Handle exceptions when listening a voice broadcast ([#7829](https://github.com/vector-im/element-android/issues/7829))
+
+In development 🚧
+----------------
+ - [Voice Broadcast] Only display a notification on the first voice chunk ([#7845](https://github.com/vector-im/element-android/issues/7845))
+ - [Poll] History list: Load more UI mechanism ([#7864](https://github.com/vector-im/element-android/issues/7864))
+
+SDK API changes ⚠️
+------------------
+ - Implement [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3912): Relation-based redactions ([#7988](https://github.com/vector-im/element-android/issues/7988))
+
+Other changes
+-------------
+ - Upgrade to Kotlin 1.8 ([#7936](https://github.com/vector-im/element-android/issues/7936))
+ - Sentry: Report sync duration and metrics for initial sync and for sync after pause. Not for regular sync. ([#7960](https://github.com/vector-im/element-android/issues/7960))
+ - [Voice Broadcast] Rework internal media players coordination ([#7979](https://github.com/vector-im/element-android/issues/7979))
+ - Support reactions on Voice Broadcast ([#7807](https://github.com/vector-im/element-android/issues/7807))
+ - Pause voice broadcast listening on new VB recording ([#7830](https://github.com/vector-im/element-android/issues/7830))
+ - Tapping slightly left or right of the 30s buttons highlights the whole cell instead of registering as button presses ([#7929](https://github.com/vector-im/element-android/issues/7929))
+
+
Changes in Element v1.5.20 (2023-01-10)
=======================================
diff --git a/build.gradle b/build.gradle
index cde07bb717..0796ddaf97 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,12 +24,12 @@ buildscript {
classpath libs.gradle.gradlePlugin
classpath libs.gradle.kotlinPlugin
classpath libs.gradle.hiltPlugin
- classpath 'com.google.firebase:firebase-appdistribution-gradle:3.1.1'
+ classpath 'com.google.firebase:firebase-appdistribution-gradle:3.2.0'
classpath 'com.google.gms:google-services:4.3.15'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6'
classpath "com.likethesalad.android:stem-plugin:2.3.0"
- classpath 'org.owasp:dependency-check-gradle:7.4.4'
+ classpath 'org.owasp:dependency-check-gradle:8.0.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.20"
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
diff --git a/changelog.d/4025.bugfix b/changelog.d/4025.bugfix
deleted file mode 100644
index 109da1c830..0000000000
--- a/changelog.d/4025.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix can't get out of a verification dialog
diff --git a/changelog.d/7807.misc b/changelog.d/7807.misc
deleted file mode 100644
index bc25a2a3d9..0000000000
--- a/changelog.d/7807.misc
+++ /dev/null
@@ -1 +0,0 @@
-Support reactions on Voice Broadcast
diff --git a/changelog.d/7824.feature b/changelog.d/7824.feature
deleted file mode 100644
index 3c8b416571..0000000000
--- a/changelog.d/7824.feature
+++ /dev/null
@@ -1 +0,0 @@
-[Poll] Warning message on decryption failure of some events
diff --git a/changelog.d/7829.bugfix b/changelog.d/7829.bugfix
deleted file mode 100644
index 705f7310f0..0000000000
--- a/changelog.d/7829.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Handle exceptions when listening a voice broadcast
diff --git a/changelog.d/7830.misc b/changelog.d/7830.misc
deleted file mode 100644
index 51053ef05d..0000000000
--- a/changelog.d/7830.misc
+++ /dev/null
@@ -1 +0,0 @@
-Pause voice broadcast listening on new VB recording
diff --git a/changelog.d/7832.bugfix b/changelog.d/7832.bugfix
deleted file mode 100644
index 871f9aabb9..0000000000
--- a/changelog.d/7832.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-[Voice Broadcast] Fix unexpected "live broadcast" in the room list
diff --git a/changelog.d/7845.wip b/changelog.d/7845.wip
deleted file mode 100644
index 8bce21499a..0000000000
--- a/changelog.d/7845.wip
+++ /dev/null
@@ -1 +0,0 @@
-[Voice Broadcast] Only display a notification on the first voice chunk
diff --git a/changelog.d/7864.wip b/changelog.d/7864.wip
deleted file mode 100644
index 9d719d92ff..0000000000
--- a/changelog.d/7864.wip
+++ /dev/null
@@ -1 +0,0 @@
-[Poll] History list: Load more UI mechanism
diff --git a/changelog.d/7895.bugfix b/changelog.d/7895.bugfix
deleted file mode 100644
index ccde7a554f..0000000000
--- a/changelog.d/7895.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Send voice message should not be allowed during a voice broadcast recording
diff --git a/changelog.d/7900.feature b/changelog.d/7900.feature
deleted file mode 100644
index c3cce1e0e6..0000000000
--- a/changelog.d/7900.feature
+++ /dev/null
@@ -1 +0,0 @@
-Render ended polls
diff --git a/changelog.d/7929.misc b/changelog.d/7929.misc
deleted file mode 100644
index c0d32ad6b2..0000000000
--- a/changelog.d/7929.misc
+++ /dev/null
@@ -1 +0,0 @@
-Tapping slightly left or right of the 30s buttons highlights the whole cell instead of registering as button presses
diff --git a/changelog.d/7930.feature b/changelog.d/7930.feature
deleted file mode 100644
index 7eb779e6ec..0000000000
--- a/changelog.d/7930.feature
+++ /dev/null
@@ -1 +0,0 @@
-"[Rich text editor] Update list item bullet appearance"
\ No newline at end of file
diff --git a/changelog.d/7936.misc b/changelog.d/7936.misc
deleted file mode 100644
index 8480d9a6bf..0000000000
--- a/changelog.d/7936.misc
+++ /dev/null
@@ -1 +0,0 @@
-Upgrade to Kotlin 1.8
diff --git a/changelog.d/7938.bugfix b/changelog.d/7938.bugfix
deleted file mode 100644
index 70218edf8a..0000000000
--- a/changelog.d/7938.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix rendering of edited polls
diff --git a/changelog.d/7962.bugfix b/changelog.d/7962.bugfix
deleted file mode 100644
index 0e35c33da4..0000000000
--- a/changelog.d/7962.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix OOM crashes.
diff --git a/dependencies.gradle b/dependencies.gradle
index 4977543822..5d7286ab1a 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -11,7 +11,7 @@ def gradle = "7.3.1"
def kotlin = "1.8.0"
def kotlinCoroutines = "1.6.4"
def dagger = "2.44.2"
-def firebaseBom = "31.1.1"
+def firebaseBom = "31.2.0"
def appDistribution = "16.0.0-beta05"
def retrofit = "2.9.0"
def markwon = "4.6.2"
@@ -27,7 +27,7 @@ def jjwt = "0.11.5"
// Temporary version to unblock #6929. Once 0.16.0 is released we should use it, and revert
// the whole commit which set version 0.16.0-SNAPSHOT
def vanniktechEmoji = "0.16.0-SNAPSHOT"
-def sentry = "6.11.0"
+def sentry = "6.12.1"
// Use 1.6.0 alpha to fix issue with test
def fragment = "1.6.0-alpha04"
// Testing
@@ -88,7 +88,7 @@ ext.libs = [
'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution",
'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution",
// Phone number https://github.com/google/libphonenumber
- 'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.13.4"
+ 'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.13.5"
],
dagger : [
'dagger' : "com.google.dagger:dagger:$dagger",
diff --git a/fastlane/metadata/android/az/short_description.txt b/fastlane/metadata/android/az-AZ/short_description.txt
similarity index 100%
rename from fastlane/metadata/android/az/short_description.txt
rename to fastlane/metadata/android/az-AZ/short_description.txt
diff --git a/fastlane/metadata/android/az-AZ/title.txt b/fastlane/metadata/android/az-AZ/title.txt
new file mode 100644
index 0000000000..907f907f99
--- /dev/null
+++ b/fastlane/metadata/android/az-AZ/title.txt
@@ -0,0 +1 @@
+Element
diff --git a/fastlane/metadata/android/az/title.txt b/fastlane/metadata/android/az/title.txt
deleted file mode 100644
index 4ca0ffb55b..0000000000
--- a/fastlane/metadata/android/az/title.txt
+++ /dev/null
@@ -1 +0,0 @@
-Element - Təhlükəsiz Mesajlaşma
diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105200.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105200.txt
new file mode 100644
index 0000000000..70ddac29a2
--- /dev/null
+++ b/fastlane/metadata/android/cs-CZ/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Hlavní změny v této verzi: Především opravy chyb!
+Úplný seznam změn: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/de-DE/changelogs/40105200.txt b/fastlane/metadata/android/de-DE/changelogs/40105200.txt
new file mode 100644
index 0000000000..549880cafb
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Die wichtigsten Änderungen in dieser Version: Hauptsächlich Fehlerbeseitigungen!
+Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/en-US/changelogs/40105220.txt b/fastlane/metadata/android/en-US/changelogs/40105220.txt
new file mode 100644
index 0000000000..5bf56d6289
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40105220.txt
@@ -0,0 +1,2 @@
+Main changes in this version: Mainly improvements on voice broadcast feature.
+Full changelog: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/et/changelogs/40105200.txt b/fastlane/metadata/android/et/changelogs/40105200.txt
new file mode 100644
index 0000000000..5d5a7fbbf2
--- /dev/null
+++ b/fastlane/metadata/android/et/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Olulisemad muutused selles versioonis: Põhiliselt veaparandused!
+Ingliskeelne muudatuste logi täismahus: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fa/changelogs/40105200.txt b/fastlane/metadata/android/fa/changelogs/40105200.txt
new file mode 100644
index 0000000000..9643f6cbdd
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+تغییرات عمده در این نگارش: عموماً رفع اشکال!
+گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105200.txt b/fastlane/metadata/android/fr-FR/changelogs/40105200.txt
new file mode 100644
index 0000000000..515dd1f882
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Principaux changements pour cette version : Principalement des corrections de bugs !
+Intégralité des changements : https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105200.txt b/fastlane/metadata/android/hu-HU/changelogs/40105200.txt
new file mode 100644
index 0000000000..339f7ce136
--- /dev/null
+++ b/fastlane/metadata/android/hu-HU/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Fő változás ebben a verzióban: Leginkább hibajavítások.
+Teljes változásnapló: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/id/changelogs/40105200.txt b/fastlane/metadata/android/id/changelogs/40105200.txt
new file mode 100644
index 0000000000..d80e0daa38
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Perubahan utama dalam versi ini: Kebanyakan perbaikan kutu!
+Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/it-IT/changelogs/40105200.txt b/fastlane/metadata/android/it-IT/changelogs/40105200.txt
new file mode 100644
index 0000000000..6d3bda5395
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Modifiche principali in questa versione: correzione di errori!
+Cronologia completa: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sk/changelogs/40105200.txt b/fastlane/metadata/android/sk/changelogs/40105200.txt
new file mode 100644
index 0000000000..24c1221752
--- /dev/null
+++ b/fastlane/metadata/android/sk/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Hlavné zmeny v tejto verzii: Hlavne oprava chýb!
+Úplný zoznam zmien: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sq/changelogs/40105160.txt b/fastlane/metadata/android/sq/changelogs/40105160.txt
new file mode 100644
index 0000000000..06cbc077c7
--- /dev/null
+++ b/fastlane/metadata/android/sq/changelogs/40105160.txt
@@ -0,0 +1,2 @@
+Ndryshimet kryesore në këtë version: Rrjedhat tani janë të aktivizuara, si parazgjedhje.
+Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sq/changelogs/40105180.txt b/fastlane/metadata/android/sq/changelogs/40105180.txt
new file mode 100644
index 0000000000..216b9368f2
--- /dev/null
+++ b/fastlane/metadata/android/sq/changelogs/40105180.txt
@@ -0,0 +1,2 @@
+Ndryshimet kryesore në këtë version: Tanimë rrjedhat janë të aktivizuara si parazgjedhje.
+Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sq/changelogs/40105200.txt b/fastlane/metadata/android/sq/changelogs/40105200.txt
new file mode 100644
index 0000000000..59fc281c6d
--- /dev/null
+++ b/fastlane/metadata/android/sq/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Ndryshimet kryesore në këtë version: Kryesisht ndreqje të metash!
+Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105130.txt b/fastlane/metadata/android/sv-SE/changelogs/40105130.txt
new file mode 100644
index 0000000000..d0f9c996af
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40105130.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: Trådar är nu aktivt som förval.
+Full ändringslogg: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105140.txt b/fastlane/metadata/android/sv-SE/changelogs/40105140.txt
new file mode 100644
index 0000000000..d0f9c996af
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40105140.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: Trådar är nu aktivt som förval.
+Full ändringslogg: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105160.txt b/fastlane/metadata/android/sv-SE/changelogs/40105160.txt
new file mode 100644
index 0000000000..d0f9c996af
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40105160.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: Trådar är nu aktivt som förval.
+Full ändringslogg: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105180.txt b/fastlane/metadata/android/sv-SE/changelogs/40105180.txt
new file mode 100644
index 0000000000..d0f9c996af
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40105180.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: Trådar är nu aktivt som förval.
+Full ändringslogg: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105200.txt b/fastlane/metadata/android/sv-SE/changelogs/40105200.txt
new file mode 100644
index 0000000000..21c54d9fd3
--- /dev/null
+++ b/fastlane/metadata/android/sv-SE/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Huvudsakliga ändringar i den här versionen: Huvudsakligen byggfixar!
+Full ändringslogg: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/uk/changelogs/40105200.txt b/fastlane/metadata/android/uk/changelogs/40105200.txt
new file mode 100644
index 0000000000..202037bfdc
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+Основні зміни в цій версії: Виправлення помилок!
+Перелік усіх змін: https://github.com/vector-im/element-android/releases
diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105200.txt b/fastlane/metadata/android/zh-TW/changelogs/40105200.txt
new file mode 100644
index 0000000000..960dc177be
--- /dev/null
+++ b/fastlane/metadata/android/zh-TW/changelogs/40105200.txt
@@ -0,0 +1,2 @@
+此版本中的主要變動:主要是臭蟲修復!
+完整的變更紀錄:https://github.com/vector-im/element-android/releases
diff --git a/library/ui-strings/src/main/res/values-ar/strings.xml b/library/ui-strings/src/main/res/values-ar/strings.xml
index a49ecc3d08..395b4c70a8 100644
--- a/library/ui-strings/src/main/res/values-ar/strings.xml
+++ b/library/ui-strings/src/main/res/values-ar/strings.xml
@@ -16,7 +16,7 @@
غيّر %1$s اسم الغُرفة إلى: %2$s
أجابَ %s على المُكالمة.
أنهى %s المُكالمة.
- جعلَ %1$s التأريخ المُستقبلي للغُرفة مرئيًا لـ %2$s
+ جعلَ %1$s عند انشاء الغرف لاحقاً تكون مرئية ل%2$s
جميع أعضاء الغُرفة، مِنَ اللَّحظة التي تمَّت دعوتهم.
جميع أعضاء الغُرفة، مِن لحظة إنضمامهم.
جميع أعضاء الغُرفة.
@@ -63,7 +63,7 @@
أرسلتَ بيانات لإعداد مُكالمة.
أجبتَ على المُكالمة.
أنهيتَ المُكالمة.
- جعلتَ التأريخ المُستقبلي للغُرفة مرئيًا لـ %1$s
+ لقدت جعلت الغرفة التي سيتم انشائها مرئيًا لـ %1$s
رقّى %s هذه الغرفة.
رقَّيتَ هذه الغرفة.
أزلتَ اسم الغُرفة
@@ -93,9 +93,9 @@
لا تغيير.
• خوادِم مُطابقة IP الحرفية محظورة الآن.
• الخوادِم المُطابقة لـ %s أُزيلت مِن قائمة السماح.
- • الخوادِم المُطابقة لـ %s مسموحة الآن.
+ • الخوادِم المُطابقة لـ %s اصبحت مسموحة الآن.
• الخوادِم المُطابقة لـ %s أُزيلت مِن قائمة الحظر.
- • الخوادِم المُطابقة لـ %s محظورة الآن.
+ • الخوادِم مُتطابقة لـ %s واصبحت محظورة الآن.
• خوادِم مُطابقة IP الحرفية مسموحة الآن.
لقد غَيَّرت قائمة الوصول لهذه الغُرفة.
غَيَّرَ %s قائمة التحكم بالوصول (ACL) لهذه الغُرفة.
@@ -234,7 +234,7 @@
انتهت المكالمة
مكالمة صورية واردة
مكالمة صوتية واردة
- المكالمة جارية
+ المكالمة جارية…
معلومات
نعم
لا
@@ -291,9 +291,7 @@
كلمة السر الجديدة
فشل تحديث كلمة السر
حُدّثت كلمة السر
- أأعرض كل رسائل %s؟
-
-سيُعيد هذا الإجراء تشغيل التطبيق وقد يأخذ بعض الوقت.
+ أأعرض كل الرسائل من %s؟ سيُعيد هذا الإجراء تشغيل التطبيق وقد يأخذ بعض الوقت.
اختر دولة
٣ أيام
أسبوع واحد
@@ -471,7 +469,7 @@
رقم الهاتف مستخدم بالفعل
معطّل
مزعج
- لا ترسل من هذا الجهاز الرسائل المعمّاة إلى الأجهزة غير المؤكّدة
+ لا ترسل من هذا الجهاز الرسائل المشفرة إلى الأجهزة غير الموثقة.
عمِّ إلى الأجهزة المؤكّدة فقط
<b>غير<b/> مؤكّدة
مؤكّدة
@@ -482,7 +480,7 @@
إن قال مدير الخادوم بأن هذا متوقع، فتأكد من أن البصمة أدناه تطابق البصمة التي وفّرها.
تغيّرت الشهادة من شهادة كنت تثق بها إلى شهادة لا تثق بها. لربما جدّد الخادوم شهادته. راسل إدارة الخادوم واسألهم عن البصمة المتوقعة.
أضِف اختصارا إلى الشاشة الرئيسية
- شاشة معلومات التطبيق في النظام
+ أظهر معلومات التطبيق في إعدادات النظام.
دعوات المكالمات
ابدأ عن الإقلاع
صدّر مفاتيح تعمية الطرفين لغرفة
@@ -566,11 +564,7 @@
وصل هذا الخادم الحدّ الأقصى للمستخدمين النشطين شهريًا بذلك لن يستطيع بعض المستخدمين الولوج لحساباتهم.
وصل خادوم المنزل هذا حدّ المستخدمين النشطين شهريًا.
يجري وصل الاتصال…
- سيجعل هذا حسابك محال الاستخدام للأبد. لن تقدر على الولوج ولن يقدر أحد على إعادة التسجيل بنفس معرّف المستخدم. سيتسبب هذا بأن يترك حسابك كل الغرف التي تشارك فيها، وستُزال تفاصيل الحساب من خادوم التعريف. هذا إجراء لا عودة فيه.
-
-حذفك لحسابك لا يتسبب بأن ننسى رسائلك التي أرسلتها (مبدئيًا). إن أردت ذلك فرجاءً أشّر على المربّع أدناه.
-
-ظهور الرسائل في «ماترِكس» شبيه كثيرًا بالبريد الإلكتروني. نسياننا لرسائلك يعني أن الرسائل التي أرسلتها لن تُشارك مع أي مستخدم جديد أو غير مسجّل، إلا أن المستخدمين المسجّلين الذي يقدرون على الوصول إليها سيمتلكون نسخة عنها.
+ سيجعل هذا حسابك محال الاستخدام للأبد. لن تقدر على تسجيل دخولك ولن يقدر أحد على إعادة التسجيل بنفس معرّف المستخدم. سيتسبب هذا بأن يترك حسابك كل الغرف التي تشارك فيها، وستُزال تفاصيل الحساب من خادم التعريف. هذا إجراء لا مجال الرجوع فيه. حذفك لحسابك لا يتسبب بأن ننسى رسائلك التي أرسلتها (مبدئيًا). إن أردت ذلك فرجاءً ضع علامة على المربّع أدناه. ظهور الرسائل في «ماترِكس» يشبه كثيرًا بالبريد الإلكتروني. نسياننا لرسائلك يعني أن الرسائل التي أرسلتها لن تُشارك مع أي مستخدم جديد أو غير مسجّل، إلا أن المستخدمين المسجّلين الذي يقدرون على الوصول إليها سيمتلكون نسخة عنها.
الرسائل الآمنة
تخطي
تم
@@ -580,7 +574,7 @@
الإعدادات المتقدمة للإشعارات
عند تسجيل الخروج الآن ستخسر مفاتيحك
النسخ الاحتياطي المفاتيح ما زال جاريا. في حال خروجك الآن لن تتمكن لاحقا من قراءة الرسائل المعماة.
- تأكد من تفعيل النسخ الاحتياطي للمفاتيح على كل أجهزتك كي لا تخسر رسائلك المعماة
+ تأكد من تفعيل النسخ الاحتياطي للمفاتيح على كل أجهزتك كي لا تخسر رسائلك المشفرة.
ينسخ احتياطيا المفاتيح…
ليس لديك تصريح لبدء إجتماع
ليس لديك تصريح لبدء إجتماع في هذه الغرفة
@@ -913,7 +907,7 @@
تحكم في محادثاتك.
تخط هذه الخطوة
احفظ وتابع
- حُفظت تفضيلاتك.
+ اذهب الى الاعدادات في اي وقت لتغير او تعديل ملفك الشخصي للتطبيق.
كل شيئ جاهز!
لننطلق
يمكنك تغييرها في أي وقت.
@@ -997,7 +991,7 @@
أنت تستعرض هذا النقاش سلفًا!
أنت تستعرض هذه الغرفة سلفًا!
منفصل عن الشبكة. تحقق من اتصالك.
- حدث عالجه مدير الغرفة.
+ حدث تم تغيره من مدير الغرفة.
ستعرض غرفك هنا. لانضمام لغرفة أو لإنشاء واحدة اضغط زر +.
ستعرض رسائلك المباشرة هنا. لبدأ محادثات جديدة اضغط زر +.
المحادثات
@@ -1175,4 +1169,30 @@
- كثيرة
- اخرى
-
\ No newline at end of file
+
+ - صفر
+ - واحد
+ - اثنان
+ - القليل
+ - العديد
+ - أخرى
+
+ ${app_name} يحتاج إلى حذف ذاكرة التخزين المؤقت حتى تكون مستحدثة، من أجل هذه الأسباب:
+\n%s
+\n
+\nملاحظة: هذا الإجراء سيؤدي إلى إعادة تشغيل التطبيق ومن الممكن أن يستغرق بعضاً من الوقت.
+ استكشف غُرف
+ تغيير التجمع
+ انشئ غرفة
+ ابدأ محادثة
+ كل المحادثات
+ أنت الذي انهيت البث الصوتي.
+
+ - صفر
+ - واحد
+ - اثنان
+ - القليل
+ - العديد
+ - أخرى
+
+
diff --git a/library/ui-strings/src/main/res/values-bg/strings.xml b/library/ui-strings/src/main/res/values-bg/strings.xml
index d3e9e599bc..5c147f59ef 100644
--- a/library/ui-strings/src/main/res/values-bg/strings.xml
+++ b/library/ui-strings/src/main/res/values-bg/strings.xml
@@ -1483,8 +1483,6 @@
Потвърди сесията
Ръчно потвърждаване чрез текстово съобщение
Потвърдете новия вход достъпващ профила ви: %1$s
- Потвърдете всички сесии за да подсигурите, че профилът и съобщенията ви са в безопасност
- Прегледайте от къде сте влезли
Шифровано от непотвърдено устройство
Нешифровано
diff --git a/library/ui-strings/src/main/res/values-ca/strings.xml b/library/ui-strings/src/main/res/values-ca/strings.xml
index b86a834a27..1f2cf1983c 100644
--- a/library/ui-strings/src/main/res/values-ca/strings.xml
+++ b/library/ui-strings/src/main/res/values-ca/strings.xml
@@ -1811,8 +1811,6 @@
No s\'ha pogut desar el fitxer multimèdia
Confirma la teva identitat verificant aquest inici de sessió i, així, poder-li donar accés als missatges xifrats.
Verifica l\'inici de sessió
- Verifica totes les teves sessions per assegurar-te que el teu compte i missatges estan segurs
- Comprova on has iniciat sessió
Xifrat amb un dispositiu no verificat
No xifrat
@@ -2293,7 +2291,6 @@
Acaba l\'enquesta
Això impedirà que la gent pugui votar i es mostraran els resultats finals de l\'enquesta.
Vols acabar l\'enquesta\?
- opció guanyadora
- Es necessita almenys %1$s opció
- Es necessiten almenys %1$s opcions
@@ -2717,9 +2714,6 @@
Els usuaris dels xats directes i sales al les quals t\'hagis unit poden veure la llista completa de les teves sessions.
\n
\nAixò els pot proporcionar més confiança de que realment parlen amb tu però, poden veure el nom de sessió que introdueixis.
- Les sessions verificades son sessions en què has iniciat sessió amb les teves credencials i s\'han verificat utilitzant una frase de seguretat o mitjançant la verificació creuada.
-\n
-\nAixò vol dir que contenen claus de xifrat dels teus missatges anteriors i confirmen als altres usuaris amb qui parles, que aquestes sessions son realment teves.
Les sessions no verificades son sessions en què has iniciat sessió amb les teves credencials però s\'hi ha fet una verificació creuada.
\n
\nAssegura\'t que reconeixes aquestes sessions especialment, ja que podrien representar un ús no autoritzat del teu compte.
@@ -2814,7 +2808,7 @@
Activa l\'editor de text enriquit
Rep notificacions en aquesta sessió.
Notificacions
- Carregant
+ Carregant
Pausa l\'emissió de veu
Reprodueix o reprèn l\'emissió de veu
Atura l\'enregistrament d\'emissió de veu
@@ -2839,4 +2833,4 @@
Format de text
Enrere 30 segons
Avança 30 segons
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-cs/strings.xml b/library/ui-strings/src/main/res/values-cs/strings.xml
index 2d2b91d645..c9d697f560 100644
--- a/library/ui-strings/src/main/res/values-cs/strings.xml
+++ b/library/ui-strings/src/main/res/values-cs/strings.xml
@@ -1469,8 +1469,6 @@
Přístup k zabezpečenému úložišti selhal
Nezašifrováno
Zašifrováno neověřeným zařízením
- Přezkoumejte, kde jste se přihlásili
- Ověřte všechny své relace za účelem bezpečí Vašeho účtu a zpráv
Ověřte nové přihlášení s přístupem na Váš účet: %1$s
Manuálně ověřit textem
Ověřit přihlášení
@@ -2313,7 +2311,6 @@
Ukončit hlasování
Toto zastaví možnost hlasování a zobrazí se konečné výsledky.
Ukončit toto hlasování\?
- vítězná volba
Ukončit hlasování
- Konečný výsledek na základě %1$d hlasu
@@ -2767,9 +2764,6 @@
\n
\nTo jim poskytuje jistotu, že s vámi skutečně mluví, ale také to znamená, že mohou vidět název relace, který zde zadáte.
Přejmenování relací
- Ověřené relace se přihlásily pomocí vašich přihlašovacích údajů a poté byly ověřeny buď pomocí vaší zabezpečené přístupové fráze, nebo křížovým ověřením.
-\n
-\nTo znamená, že uchovávají šifrovací klíče pro vaše předchozí zprávy a potvrzují ostatním uživatelům, se kterými komunikujete, že tyto relace jste skutečně vy.
Ověřené relace
Neověřené relace jsou relace, které se přihlásily pomocí vašich přihlašovacích údajů, ale nebyly křížově ověřeny.
\n
@@ -2868,7 +2862,7 @@
Druhé zařízení je již přihlášeno.
Při nastavování zabezpečeného zasílání zpráv se vyskytl problém se zabezpečením. Může být napadena jedna z následujících věcí: váš domovský server; vaše internetové připojení; vaše zařízení;
Žádost se nezdařila.
- Ukládání do vyrovnávací paměti…
+ Ukládání do vyrovnávací paměti…
Pozastavit hlasové vysílání
Přehrát nebo obnovit hlasové vysílání
Ukončit záznam hlasového vysílání
@@ -2955,4 +2949,33 @@
V této místnosti nejsou žádné aktivní hlasování
Aktivní hlasování
Historie hlasování
-
\ No newline at end of file
+ Ukončené hlasování
+ Hlasování
+ ukončil(a) hlasování.
+ Hlasování bylo ukončeno.
+ Váš domovský server zatím nepodporuje zobrazení seznamu vláken.
+ Nelze přehrát toto hlasové vysílání.
+ Hlasové vysílání bylo zahájeno
+ Kvůli chybám při dešifrování nemusí být některé hlasy započítány
+ Chyba při načítání hlasování.
+ Načíst další hlasování
+ Zobrazení hlasování
+
+ - Za uplynulý den nejsou k dispozici žádná hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další hlasování.
+ - Za poslední %1$d dny nejsou k dispozici žádná hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další hlasování.
+ - Za posledních %1$d dní nejsou k dispozici žádná hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další hlasování.
+
+
+ - Za uplynulý den nejsou žádná aktivní hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další ankety.
+ - Za poslední %1$d dny nejsou žádná aktivní hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další ankety.
+ - Za posledních %1$d dní nejsou žádná aktivní hlasování.
+\nPro zobrazení hlasování z předchozích dnů načtěte další ankety.
+
+ Hlasovou zprávu nelze spustit, protože právě nahráváte živé vysílání. Ukončete prosím živé vysílání, abyste mohli začít nahrávat hlasovou zprávu
+ Nelze spustit hlasovou zprávu
+
diff --git a/library/ui-strings/src/main/res/values-de/strings.xml b/library/ui-strings/src/main/res/values-de/strings.xml
index 52b8f0c716..f0e5a7bb8d 100644
--- a/library/ui-strings/src/main/res/values-de/strings.xml
+++ b/library/ui-strings/src/main/res/values-de/strings.xml
@@ -1427,8 +1427,6 @@
Konnte nicht auf gesicherten Speicher zugreifen
Unverschlüsselt
Verschlüsselt von einem nicht verifiziertem Gerät
- Überprüfe, wo du angemeldet bist
- Verifiziere alle deine Sitzungen, um sicherzustellen, dass dein Konto und deine Nachrichten sicher sind
Bestätige neue Anmeldung zu deinem Konto: %1$s
Verifiziere manuell mit einem Text
Anmeldung verifizieren
@@ -2319,7 +2317,6 @@
Umfrage beenden
Dies verhindert, dass andere Personen abstimmen können, und zeigt die Endergebnisse der Umfrage an.
Diese Umfrage beenden\?
- Gewinneroption
Umfrage beenden
- Endgültiges Ergebnis basiert auf %1$d Stimme
@@ -2711,9 +2708,6 @@
Andere Nutzer in Direktnachrichten und Räumen, in denen du dich befindest, können eine vollständige Liste deiner Sitzungen einsehen.
\n
\nDies gibt ihnen die Sicherheit, dass sie auch wirklich mit dir kommunizieren. Allerdings bedeutet es auch, dass sie die Sitzungsnamen sehen können, die du hier angibst.
- Verifizierte Sitzungen wurden mit deinen Daten angemeldet und anschließend mit deiner Sicherheitspassphrase oder durch Quersignierung verifiziert.
-\n
-\nDies bedeutet, dass sie die Verschlüsselungs-Schlüssel für deine bisherigen Nachrichten besitzen und anderen Nutzern bestätigen können, dass diese Sitzungen tatsächlich von dir stammen.
Sitzungen umbenennen
Verifizierte Sitzungen
Nicht verifizierte Sitzungen sind jene, die angemeldet, aber nicht quer signiert sind.
@@ -2815,7 +2809,7 @@
Die Anfrage ist fehlgeschlagen.
Abspielen oder fortsetzen der Sprachübertragung
Fortsetzen der Sprachübertragung
- Puffere …
+ Puffere …
Pausiere Sprachübertragung
Stoppe Aufzeichnung der Sprachübertragung
Pausiere Aufzeichnung der Sprachübertragung
@@ -2893,9 +2887,34 @@
Zugriffstoken
Unsortierte Liste umschalten
Nummerierte Liste umschalten
- In diesem Raum gibt es noch keine abgeschlossenen Umfragen
+ In diesem Raum gibt es keine abgeschlossenen Umfragen
Vergangene Umfragen
In diesem Raum gibt es keine aktiven Umfragen
Aktive Umfragen
Umfrageverlauf
-
\ No newline at end of file
+ Beendete Umfrage
+ Umfrage
+ beendete eine Umfrage.
+ Umfrage beendet.
+ Dein Heim-Server unterstützt noch nicht das Auflisten von Threads.
+ Eine Sprachübertragung wurde begonnen
+ Wiedergabe der Sprachübertragung nicht möglich.
+ Evtl. werden infolge von Entschlüsselungsfehlern einige Stimmen nicht gezählt
+ Fehler beim Laden der Umfragen.
+ Weitere Umfragen laden
+ Zeige Umfragen an
+
+ - Für den vergangenen Tag sind keine aktiven Umfragen verfügbar.
+\nLade weitere Umfragen, um die der vorherigen Tage zu sehen.
+ - Für die vergangenen %1$d Tage sind keine aktiven Umfragen verfügbar.
+\nLade weitere Umfragen, um die der vorherigen Tage zu sehen.
+
+
+ - Für den vergangenen Tag sind keine beendeten Umfragen verfügbar.
+\nLade weitere Umfragen, um die der vorherigen Tage zu sehen.
+ - Für die vergangenen %1$d Tage sind keine beendeten Umfragen verfügbar.
+\nLade weitere Umfragen, um die der vorherigen Tage zu sehen.
+
+ Du kannst keine Sprachnachricht beginnen, da du im Moment eine Echtzeitübertragung aufzeichnest. Bitte beende deine Sprachübertragung, um ein Gespräch zu beginnen
+ Kann Sprachnachricht nicht beginnen
+
diff --git a/library/ui-strings/src/main/res/values-eo/strings.xml b/library/ui-strings/src/main/res/values-eo/strings.xml
index e417d183bf..0aa395dcce 100644
--- a/library/ui-strings/src/main/res/values-eo/strings.xml
+++ b/library/ui-strings/src/main/res/values-eo/strings.xml
@@ -1483,8 +1483,6 @@
Aldoni ĉambranojn
Konfirmu vian identecon per kontrolo de ĉi tiu saluto, donante al ĝi aliron al ĉifritaj mesaĝoj.
Kontrolu la novan saluton, kiu aliras vian konton: %1$s
- Rekontrolu ĉiujn viajn salutaĵojn por certigi, ke viaj konto kaj mesaĝoj estas sekuraj
- Rekontrolu, kie vi salutis
- Montri la aparaton per kiu vi povas kontroli nun
- Montri %d aparatojn per kiuj vi povas kontroli nun
@@ -2200,4 +2198,4 @@
Aroj
- Iom uzantoj reatentita
\@room
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-es/strings.xml b/library/ui-strings/src/main/res/values-es/strings.xml
index c06442b5d0..f14464d957 100644
--- a/library/ui-strings/src/main/res/values-es/strings.xml
+++ b/library/ui-strings/src/main/res/values-es/strings.xml
@@ -1592,8 +1592,6 @@
No se pudo acceder al almacenamiento seguro
Sin cifrar
Cifrado por un dispositivo no verificado
- Revise dónde inició sesión
- Verifique todas sus sesiones para asegurarse de que su cuenta y sus mensajes estén seguros
Verifique el nuevo inicio de sesión accediendo a su cuenta: %1$s
Verificar manualmente por texto
Verificación interactiva por emoji
@@ -2386,7 +2384,6 @@
Finalizar encuesta
Esto evitará que las personas puedan votar y mostrará los resultados finales de la encuesta.
¿Finalizar encuesta\?
- opción ganadora
Finalizar encuesta
- Resultado final basado en %1$d voto
@@ -2688,4 +2685,4 @@
Mostrar chats recientes en el menú de compartir sistema
No enviar nunca mensajes cifrados a sesiones sin verificar en esta sala.
Restan %1$s
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-et/strings.xml b/library/ui-strings/src/main/res/values-et/strings.xml
index 1e8e2b989e..1d7b96d2f9 100644
--- a/library/ui-strings/src/main/res/values-et/strings.xml
+++ b/library/ui-strings/src/main/res/values-et/strings.xml
@@ -1304,8 +1304,6 @@
Turvahoidla kasutamine ei õnnestu
Krüptimata
Krüptitud verifitseerimata seadme poolt
- Vaata üle, kust sa oled Matrix\'i võrku loginud
- Selleks et sinu konto ja sõnumid oleks turvatud, verifitseeri kõik oma sessioonid
Verifitseeri uus kasutajasessioon, mis pruugib sinu kontot: %1$s
Verifitseeri käsitsi etteantud teksti abil
Verifitseeri sisselogimissessioon
@@ -2318,7 +2316,6 @@
Laadi fail üles
Saada pilte ja videosid
Ava kaamera
- populaarsem valik
Kui sõnumite dekrüptimisel tekib viga, siis rakendus saadab selle kohta automaatse teate arendajatele
Automaatselt teata dekrüptimise vigadest.
Asenda kuvatava nime värvid
@@ -2706,9 +2703,6 @@
\n
\nSee tähendab, et nad võivad uskuda, et tegemist on tõesti sinuga. Samal ajal näevad ka siin sisestatud sessiooninime.
Sessioonide nimede muutmine
- Verifitseeritud sessioonid on sellised, kuhu sa oled oma kasutajanime ja salasõnaga sisse loginud ning mille puhul oled risttunnustamise läbi teinud või paroolifraasi abil ta turvaliseks märkinud.
-\n
-\nSee tähendab, et nendes sessioonides on olemas sinu varasemate sõnumite krüptovõtmed ja teistele osapooltele on nad tuvastatavad nii, et tegemist on tõesti sinuga.
Verifitseeritud sessioonid
Verifitseerimata sessioonid on sellised, kuhu sa oled oma kasutajanime ja salasõnaga sisse loginud, kuid mille puhul on risttunnustamine tegemata.
\n
@@ -2805,7 +2799,7 @@
Teine seade on juba võrku loginud.
Turvalise sõnumivahetuse ülesseadmisel tekkis turvaviga. Üks kolmest võib olla sattunud vale osapoole kontrolli alla: sinu koduserver, sinu internetiühendus või sinu seade;
Päring ei õnnestunud.
- Andmed on puhverdamisel…
+ Andmed on puhverdamisel…
Alusta või jätka ringhäälingukõne esitamist
Lõpeta ringhäälingukõne salvestamine
Peata ringhäälingukõne salvestamine
@@ -2890,4 +2884,29 @@
Lülita täpploend sisse/välja
Pääsuluba
Sinu pääsuluba annab täismahulise ligipääsu sinu kasutajakontole. Palun ära jaga seda teistega.
-
\ No newline at end of file
+ Lõppenud küsitlus
+ Küsitlus on lõppenud.
+ lõpetas küsitluse.
+ Küsitlus
+ Sinu koduserver veel ei toeta jutulõngade loendit.
+ Alustasime ringhäälingukõnega
+ Selle ringhäälingukõne esitamine ei õnnestu.
+ Krüptimisvigade tõttu jääb osa hääli lugemata
+
+ - Möödunud päevas polnud ühtegi toimumas olnud küsitlust.
+\nVarasemate päevade vaatamiseks laadi veel küsitlusi.
+ - Möödunud %1$d päeva jooksul polnud ühtegi toimumas olnud küsitlust.
+\nVarasemate päevade vaatamiseks laadi veel küsitlusi.
+
+
+ - Möödunud päevas polnud ühtegi küsitlust.
+\nVarasemate päevade vaatamiseks laadi veel küsitlusi.
+ - Möödunud %1$d päeva jooksul polnud ühtegi küsitlust.
+\nVarasemate päevade vaatamiseks laadi veel küsitlusi.
+
+ Küsitluste kuvamise ootel
+ Laadi veel küsitlusi
+ Viga küsitluste laadimisel.
+ Häälsõnumi esitamine ei õnnestu
+ Kuna sa hetkel salvestad ringhäälingukõnet, siis häälsõnumi salvestamine või esitamine ei õnnestu. Selleks palun lõpeta ringhäälingukõne
+
diff --git a/library/ui-strings/src/main/res/values-eu/strings.xml b/library/ui-strings/src/main/res/values-eu/strings.xml
index f1f834ee04..b045cc8c70 100644
--- a/library/ui-strings/src/main/res/values-eu/strings.xml
+++ b/library/ui-strings/src/main/res/values-eu/strings.xml
@@ -1785,8 +1785,6 @@ Errore hau ${app_name}-en kontroletik kanpo dago. Ez dago Google konturik gailua
Zifratu gabe
Egiaztatu gabeko gailu batek zifratua
- Berrikusi non hasi duzun saioa
- Egiaztatu zure saio guztiak kontua eta mezuak seguru daudela bermatzeko
Egiaztatu zure kontuan hasitako saio berria: %1$s
Egiaztatu eskuz testu bidez
diff --git a/library/ui-strings/src/main/res/values-fa/strings.xml b/library/ui-strings/src/main/res/values-fa/strings.xml
index 4db3812237..1b726a2428 100644
--- a/library/ui-strings/src/main/res/values-fa/strings.xml
+++ b/library/ui-strings/src/main/res/values-fa/strings.xml
@@ -1106,8 +1106,6 @@
یا دیگر کارههای ماتریکس دادای قابلیت ورود چندگانه
تأیید دستی با متن
تأیید ورود جدیدی که به حسابتان دسترسی دارد: %1$s
- تأیید همهٔ نشستهایتان برای اطمینان از این که حساب و پیامهایتان امنند
- بازبینی جاهایی که وارد شدهاید
تأیید برهمکنشی با اموجی
تأیید ورود
رمزنشده
@@ -2275,7 +2273,6 @@
پایان نظرسنجی
این کار اجازهٔ رأی دادن افراد را پایان داده و نتیجهٔ نهایی نظرسنجی را نمایش خواهد داد.
پایان این نظرسنجی؟
- گزینهٔ غالب
پایان نظرسنجی
- نتیجهٔ نهایی بر مبنای %1$d رأی
@@ -2783,7 +2780,7 @@
نظرسنجیها
پیوستها
برچسبها
- میانگیری…
+ میانگیری…
زنده
تأیید
۳
@@ -2859,9 +2856,6 @@
نشستهای تأیید شده آنهاییند که پس از ورود عبارت عبورتان یا تأیید هویتتان با نشست تأیید شدهای دیگر، واردشان شدهاید.
\n
\nیعنی تمامی کلیدهای لارم برای رمزگشایی پیامهای رمزنگاشتهتان را داشته و این تأیید را به دیگران میدهند که به این نشست اطمینان دارید.
- نشستهای تأیید شده به حسابتان وارد و با عبارت عبور امنتان یا تأیید متقابل تأیید شدهاند.
-\n
-\nیعنی کلیدهای رمزنگاری پیامهای پیشینتان را داشته و به دیگر کاربران این تأیید را میدهند که این نشست، خودتان هستید.
نشستهای تأیید نشده نشستهاییند که به آنها وارد شدهاید، ولی تأیید متقبالشان نکردهاید.
\n
\nباید به طور خاص مطمئن شوید که این نشستها را میشناسید؛ چرا که میتوانند نشاندهندهٔ استفادهٔ تأییدنشده از حسابتان باشند.
@@ -2899,4 +2893,29 @@
هیچ نظرسنجی فعّالی در این اتاق وجود ندارد
نظرسنجیهای فعّال
تاریخچهٔ نظرسنجیها
-
\ No newline at end of file
+ نظرسنجی پایان یافته
+ نظرسنجی
+ به نظرسنجیای پایان داد.
+ به نظرسنجی پایان داد.
+ کارساز خانگیتان هنوز از سیاهه کردن رشتهها پشتیبانی نمیکند.
+ ناتوان در پخش این صدا.
+ پخش صوتی را آغاز کرد
+ به خاطر خطاهای رمزگشایی، ممکن است برخی رأیها شمرده نشوند
+ خطا در واکشی نظرسنجیها.
+ بار کردن نظرسنجیهای بیشتر
+ نشان دادن نظرسنجیها
+
+ - نظرسنجی گذشتهای برای روز گذشته وجود ندارد.
+\nبرای دیدن نظرسنجیهای روزهای پیش، نظرسنجیهای بیشتری بار کنید.
+ - نظرسنجی گذشتهای برای %1$d روز گذشته وجود ندارد.
+\nبرای دیدن نظرسنجیهای روزهای پیش، نظرسنجیهای بیشتری بار کنید.
+
+
+ - نظرسنجی فعّالی برای روز گذشته وجود ندارد.
+\nبرای دیدن نظرسنجیهای روزهای پیش، نظرسنجیهای بیشتری بار کنید.
+ - نظرسنجی فعّالی برای %1$d روز گذشته وجود ندارد.
+\nبرای دیدن نظرسنجیهای روزهای پیش، نظرسنجیهای بیشتری بار کنید.
+
+ از آنجا که در حال ضبط پخشی زندهاید، نمیتوانید پیامی صوتی را آغاز کنید. لطفاً برای آغاز ضبط یک پیام صوتی، پخش زندهتان را پایان دهید
+ نمیتوان پخش صوتی را آغاز کرد
+
diff --git a/library/ui-strings/src/main/res/values-fi/strings.xml b/library/ui-strings/src/main/res/values-fi/strings.xml
index 4976f49a92..c1cc5da2c8 100644
--- a/library/ui-strings/src/main/res/values-fi/strings.xml
+++ b/library/ui-strings/src/main/res/values-fi/strings.xml
@@ -1717,8 +1717,6 @@
Valitse käyttäjänimi.
Vahvista vuorovaikutteisesti emojilla
Vahvista kirjautuminen
- Vahvista kaikki istuntosi varmistaaksesi, että tilisi ja viestisi ovat turvassa
- Katselmoi missä olet sisäänkirjautuneena
Salattu vahvistamattomalla laitteella
Salaamaton
Käytä palautusavainta
@@ -2309,4 +2307,4 @@
- %1$d valittu
- %1$d valittu
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-fr-rCA/strings.xml b/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
index 94db2935a7..cd39fa3381 100644
--- a/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
+++ b/library/ui-strings/src/main/res/values-fr-rCA/strings.xml
@@ -640,8 +640,6 @@
Vérifier la connexion
Vérifier manuellement avec un texte
Vérifiez la nouvelle connexion accédant à votre compte : %1$s
- Vérifiez toutes les sessions pour vous assurer que votre compte et vos messages sont en sécurité
- Vérifiez où vous vous êtes connecté
Chiffré par un appareil non vérifié
Non chiffré
envoie de la neige ❄️
diff --git a/library/ui-strings/src/main/res/values-fr/strings.xml b/library/ui-strings/src/main/res/values-fr/strings.xml
index cb1684f834..e45211b61a 100644
--- a/library/ui-strings/src/main/res/values-fr/strings.xml
+++ b/library/ui-strings/src/main/res/values-fr/strings.xml
@@ -1413,8 +1413,6 @@
Nous n’avons pas pu créer votre conversation privée. Vérifiez les utilisateurs que vous souhaitez inviter et réessayez.
Non chiffré
Chiffré par un appareil non vérifié
- Vérifiez où vous vous êtes connecté
- Vérifiez toutes les sessions pour vous assurer que votre compte et vos messages sont en sécurité
Vérifiez la nouvelle connexion accédant à votre compte : %1$s
%1$s : %2$s
%1$s : %2$s %3$s
@@ -2272,7 +2270,6 @@
Terminer le sondage
Cela empêchera les gens de voter et affichera le résultat final du sondage.
Terminer ce sondage \?
- option gagnante
Terminer le sondage
- Résultat final sur la base de %1$d vote
@@ -2713,9 +2710,6 @@
\n
\nCela leur fournit une preuve de confiance que c’est bien avec vous qu\'ils communiquent, mais cela veut également dire qu’ils peuvent voir le nom de la session que vous saisissez ici.
Renommer les sessions
- Les sessions vérifiées sont celles qui sont identifiées avec votre mot de passe puis vérifiée, soit à l’aide de votre phrase de sécurité, ou bien par la vérification croisée.
-\n
-\nCela signifie qu’elles possèdent les clés de chiffrement de vos messages passés, et certifient aux autres utilisateurs avec qui vous communiquez que ces sessions viennent vraiment de vous.
Sessions vérifiées
Les sessions non vérifiées sont celles qui sont identifiées avec votre mot de passe sans avoir fait de vérification croisée.
\n
@@ -2814,7 +2808,7 @@
Vous pouvez utiliser cet appareil pour connecter un appareil mobile ou un client web avec un QR code. Il y a deux façons de le faire :
Se connecter avec un QR code
Scanner le QR code
- Mise en mémoire tampon…
+ Mise en mémoire tampon…
Mettre en pause la diffusion audio
Lire ou continuer la diffusion audio
Arrêter l’enregistrement de la diffusion audio
@@ -2899,4 +2893,29 @@
Il n’y a aucun sondage en cours dans ce salon
Sondages actifs
Historique des sondages
-
\ No newline at end of file
+ Sondage terminé
+ Sondage
+ a terminé un sondage.
+ A terminé le sondage.
+ Votre serveur d’accueil ne prend pas encore en charge l’affichage de la liste des fils de discussion.
+ Impossible de lire cette diffusion audio.
+ A démarré une diffusion audio
+ À cause d’erreurs de déchiffrement, certains votes pourraient ne pas avoir été pris en compte
+ Erreur lors de la récupération des sondages.
+ Charger plus de sondages
+ Affichage des sondages
+
+ - Il n’y a aucun sondage terminé depuis hier.
+\nChargez plus de sondages pour voir les sondages des jours précédents.
+ - Il n’y a aucun sondage terminé depuis %1$d jours.
+\nChargez plus de sondages pour voir les sondages des jours précédents.
+
+
+ - Il n’y a aucun sondage actif depuis hier.
+\nChargez plus de sondages pour voir les sondages des jours précédents.
+ - Il n’y a aucun sondage actif depuis %1$d jours.
+\nChargez plus de sondages pour voir les sondages des jours précédents.
+
+ Vous ne pouvez pas commencer un message vocal car vous êtes en train d’enregistrer une diffusion en direct. Veuillez terminer cette diffusion pour commencer un message vocal
+ Impossible de démarrer un message vocal
+
diff --git a/library/ui-strings/src/main/res/values-hu/strings.xml b/library/ui-strings/src/main/res/values-hu/strings.xml
index 9fdad2dbf0..0aa70cea55 100644
--- a/library/ui-strings/src/main/res/values-hu/strings.xml
+++ b/library/ui-strings/src/main/res/values-hu/strings.xml
@@ -1361,8 +1361,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
A biztonsági tárolóhoz nem sikerült hozzáférni
Titkosítatlan
Ellenőrizetlen eszközzel titkosította
- Tekintsd át hol vagy bejelentkezve
- Ellenőrizd minden munkamenetedet, hogy a fiókod és az üzeneteid biztonságban legyenek
Ellenőrizd ezt az új bejelentkezést ami hozzáfér a fiókodhoz: %1$s
Manuális szöveges ellenőrzés
Belépés ellenőrzése
@@ -2308,7 +2306,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
\n
\nElolvashatod a feltételeinket %s.
Segíts az ${app_name}-et jobbá tenni
- nyerő válasz
Jogi dolgok
A változások életbelépéséhez indítsd újra az alkalmazást.
LaTeX matematikai szintaxis engedélyezése
@@ -2712,9 +2709,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
Más felhasználók akikkel közvetlenül vagy szobában beszélgetsz látják a teljes listát a munkameneteidről.
\n
\nEzzel ők biztosak lehetnek abban, hogy ténylegesen veled beszélgetnek. Ez azt is jelenti, hogy látják a munkamenet nevét amit itt megadsz.
- Ellenőrzött munkamenetbe a neveddel és jelszavaddal léptek be és ellenőrizve lett vagy a biztonsági jelmondattal vagy másik munkamenetből.
-\n
-\nEz azt jelenti, hogy tartalmazzák a titkosítási kulcsokat az régi üzenetekhez, és biztosítja a többieket a kommunikációban, hogy ezt a munkamenetet tényleg te használod.
Aláhúzott
Áthúzott
Dőlt
@@ -2814,7 +2808,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
A kérés sikertelen.
Hang közvetítés felvételéhez és a szoba idővonalára küldéséhez.
Hang közvetítés engedélyezése
- Pufferelés…
+ Pufferelés…
Hang közvetítés szüneteltetése
Hang közvetítés lejátszása vagy lejátszás folytatása
Hang közvetítés felvétel leállítása
@@ -2899,4 +2893,29 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze
Nincsenek aktív szavazások ebben a szobában
Aktív szavazások
Szavazás alakulása
-
\ No newline at end of file
+ Lezárt szavazások
+ Szavazás
+ befejezte a szavazást.
+ Szavazás vége.
+ A matrix szerver nem támogatja az üzenetszálak listázását.
+ A hang közvetítés nem játszható le.
+ Hang közvetítés indítva
+ Visszafejtési hibák miatt néhány szavazat nem kerül beszámításra
+ Szavazás betöltési hiba.
+ Még több szavazás betöltése
+ Szavazások megjelenítése
+
+ - Egy napja nincs aktív szavazás.
+\nTovábbi szavazások betöltése a régi szavazások megjelenítéséhez.
+ - %1$d napja nincs aktív szavazás.
+\nTovábbi szavazások betöltése a régi szavazások megjelenítéséhez.
+
+
+ - Egy napja nincs aktív szavazás.
+\nTovábbi szavazások betöltése a régi szavazások megjelenítéséhez.
+ - %1$d napja nincs aktív szavazás.
+\nTovábbi szavazások betöltése a régi szavazások megjelenítéséhez.
+
+ Nem lehet hang üzenetet indítani élő közvetítés felvétele közben. Az élő közvetítés bejezése szükséges a hang üzenet indításához
+ Hang üzenetet nem lehet elindítani
+
diff --git a/library/ui-strings/src/main/res/values-hy/strings.xml b/library/ui-strings/src/main/res/values-hy/strings.xml
new file mode 100644
index 0000000000..a444d625fb
--- /dev/null
+++ b/library/ui-strings/src/main/res/values-hy/strings.xml
@@ -0,0 +1,106 @@
+
+
+ Դուք մերժել եք հրավերը։ Պատճառ` %1$s
+ %1$sը մերժել է հրավերը։ Պատճառը` %2$s
+ Դուք լքել եք։ Պատճառը` %1$s
+ %1$sը լքել է սենյակը։ Պատճառը` %2$s
+ %1$sը միացել է։ Պատճառը` %2$s
+ %1$sը լքել է։ Պատճառը` %2$s
+ Դուք լքել եք սենյակը։ Պատճառը` %1$s
+ Դուք միացել եք։ Պատճառը` %1$s
+ Դուք միացել եք սենյակին։ Պատճառը` %1$s
+ %1$sը միացել է սենյակին։ Պատճառը` %2$s
+ %1$sը հրավիրել է Ձեզ։ Պատճառը` %2$s
+ Հաղորդագրությունը ուղարկվում է…
+ Ուղարկողի սարքավորումը մեզ չի ուղարկել այս հաղորդագրության բանալիները։
+ %sը ավարտել է զանգը։
+ Դուք պատասխանել եք զանգին։
+ %sը պատասխանել է զանգին։
+ Դուք հրավիրել եք %1$sին։ Պատճառը` %2$s
+ %1$sը հրավիրել է %2$sին։ Պատճառը` %3$s
+ Հաղորդագրությունը ուղարկվել է
+ Դատարկ սենյակ
+
+ - %1$sը, %2$sը, %3$sը և %4$d ուրիշը
+ - %1$sը, %2$sը, %3$sը և %4$d ուրիշները
+
+ %1$sը, %2$sը, %3$sը և %4$sը
+ %1$sը, %2$sը և %3$sը
+ %1$sը և %2$sը
+ Սենյակի Հրավեր
+ Էլ-փոստի հասցե
+ Հեռախոսահամար
+ Դուք այս սենյակին միանալու թույլտվություն չունեք
+ Ուսումնասիրել Սենյակներ
+ Ստեղծել Տարածություն
+ Բոլոր Զրույցները
+ Սկսել Զրույց
+ Ստեղծել Սենյակ
+ Matrix-ի սխալ
+ Հնարավոր չէ ուղարկել հաղորդագրությունը
+ ** Հնարավոր չէ վերծանել %sը **
+ Լռելյայն
+ Մոդերատոր
+ Ադմին
+ Դուք հրավիրել եք %1$sին
+ %1$s հրավիրել է %2$sին
+ Դուք սենյակին միանալու հրավեր եք ուղարկել %1$sին
+ %1$sը սենյակին միանալու հրավեր է ուղարկել%2$sին
+ Դուք հեռացրել եք սենյակի անունը
+ %1$sը հեռացրել է սենյակի անունը
+ Փոփոխություն չկա։
+ ցանկացածը։
+ սենյակի բոլոր անդամները։
+ սենյակի բոլոր անդամները, իրենց միանալու պահից սկսած։
+ սենյակի բոլոր անդամները, իրենց հրավիրման պահից սկսած։
+ Դուք ապագա հաղորդագրությունները տեսանելի եք դարձրել %1$sին
+ %1$sը ապագա հաղորդագրությունները տեսանելի է դարձրել %2$sին
+ Դուք սենյակի ապագա պատմությունը տեսանելի եք դարձրել %1$sին
+ %1$sը սենյակի ապագա պատմությունը տեսանելի է դարձրել %2$sին
+ Դուք ավարտել եք զանգը։
+ Դուք սենյակի անունը փոխել եք %1$s
+ %1$sը սենյակի անունը փոխել է %2$s
+ %1$s ստեղծել է այս քննարկումը
+ Դուք ստեղծել եք այս սենյակը
+ %1$s ստեղծել է այս սենյակը
+
+ - %1$d ընտրված է
+ - %1$d ընտրված են
+
+ Ձեր հրավերը
+ %sի հրավերը
+ Դուք հեռացրել եք %1$sին
+ %1$sը հեռացրել է %2$sին
+ Դուք մերժել եք հրավերը
+ %1$s մերժել է հրավերը
+ Դուք լքել եք սենյակը
+ %1$s լքել է սենյակը
+ Դուք լքել եք սենյակը
+ %1$s լքել է սենյակը
+ Դուք միացել եք
+ %1$sը միացել է
+ Դուք միացել եք սենյակին
+ %1$sը միացել է սենյակին
+ %1$sը հրավիրել է Ձեզ
+ Դուք հրավիրել եք %1$sին
+ %1$sը հրավիրել է %2$sին
+ Դուք ստեղծել եք այս քննարկումը
+ Դուք հեռացրել եք սենյակի գլխավոր հասցեն։
+ %1$sը հեռացրել է սենյակի գլխավոր հասցեն։
+ Դուք սենյակի գլխավոր հասցեն դրել եք %1$sը։
+ %1$sը սենյակի գլխավոր հասցեն դրել է %2$sը։
+
+ - Դուք ավելացրել եք %1$sին որպես սենյակի հասցե
+ - Դուք ավելացրել եք %1$sին որպես սենյակի հասցեներ
+
+
+ - %1$sը ավելացրել է %2$sին որպես սենյակի հասցե
+ - %1$sը ավելացրել է %2$sին որպես սենյակի հասցեներ
+
+ Դուք ետ եք կանչել %1$sի հրավերը։ Պատճառը` %2$s
+ %1$sը ետ է կանչել %2$sի հրավերը։ Պատճառը` %3$s
+ %1$sը ընդունել է %2$sի համար հրավերը։ Պատճառը` %3$s
+ Դուք ընդունել եք %1$sի համար հրավերը։ Պատճառը` %2$s
+ Դուք հեռացրել եք %1$sին։ Պատճառը` %2$s
+ %1$sը հեռացրել է %2$sին։ Պատճառը` %3$s
+
\ No newline at end of file
diff --git a/library/ui-strings/src/main/res/values-in/strings.xml b/library/ui-strings/src/main/res/values-in/strings.xml
index 8896037037..4c524df727 100644
--- a/library/ui-strings/src/main/res/values-in/strings.xml
+++ b/library/ui-strings/src/main/res/values-in/strings.xml
@@ -1957,8 +1957,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
Verifikasi secara Manual oleh Teks
Verifikasi login
Verifikasi login baru yang mengakses akun Anda: %1$s
- Verifikasi semua sesi Anda untuk memastikan akun & pesan Anda aman
- Lihat mana Anda masuk
Dienkripsi oleh perangkat yang tidak diverifikasi
Tidak Dienkripsi
mengirim salju ❄️
@@ -2233,7 +2231,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
Akhiri poll
Ini akan menghentikan orang-orang untuk dapat memberikan suara dan akan menampilkan hasil akhir poll.
Akhiri poll ini\?
- opsi pemenang
Akhiri poll
- Hasil akhir berdasarkan oleh %1$d suara
@@ -2661,9 +2658,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
\n
\nIni memberikan mereka kepastian bahwa mereka berbicara dengan Anda, tetapi ini juga berarti bahwa mereka dapat melihat nama sesi yang Anda masukkan di sini.
Mengubah nama sesi
- Sesi yang terverifikasi telah masuk dengan kredensial Anda dan juga telah diverifikasi, menggunakan frasa sandi atau memverifikasi secara silang.
-\n
-\nIni berarti mereka memegang kunci enkripsi ke pesan Anda sebelumnya, dan mengonfirmasi pengguna lain yang Anda berkomunikasi bahwa sesi ini memang Anda.
Sesi tidak aktif
Sesi belum diverifikasi
Sesi terverifikasi
@@ -2762,7 +2756,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
Permintaan gagal.
Memungkinkan untuk merekam dan mengirim siaran suara dalam lini masa ruangan.
Aktifkan siaran suara
- Memuat…
+ Memuat…
Jeda siaran suara
Mainkan atau lanjutkan siaran suara
Hentikan rekaman siaran suara
@@ -2845,4 +2839,23 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.
Tidak ada pemungutan suara yang aktif di ruangan ini
Pemungutan suara aktif
Riwayat pemungutan suara
-
\ No newline at end of file
+ Pemungutan suara diakhiri
+ Pemungutan suara
+ mengakhiri pemungutan suara.
+ Mengakhiri pemungutan suara.
+ Homeserver Anda belum mendukung pendaftaran utasan.
+ Tidak dapat memutar siaran suara ini.
+ Memulai sebuah siaran suara
+ Karena kesalahan enkripsi, beberapa suara mungkin tidak terhitung
+ Terjadi kesalahan mendapatkan pemungutan suara.
+ Muat lebih banyak pemungutan suara
+ Menampilkan pemungutan suara
+
+ - Tidak ada pemungutan suara yang lalu %1$d hari terakhir.
+\nMuat lebih banyak pemungutan suara untuk melihat pemungutan suara untuk hari sebelumnya.
+
+
+ - Tidak ada pemungutan suara aktif %1$d hari terakhir.
+\nMuat lebih banyak pemungutan suara untuk melihat pemungutan suara untuk hari sebelumnya.
+
+
diff --git a/library/ui-strings/src/main/res/values-is/strings.xml b/library/ui-strings/src/main/res/values-is/strings.xml
index ceb4d614de..ba505bc0a3 100644
--- a/library/ui-strings/src/main/res/values-is/strings.xml
+++ b/library/ui-strings/src/main/res/values-is/strings.xml
@@ -851,7 +851,6 @@
- %1$d atkvæði greidd. Greiddu atkvæði til að sjá útkomuna
Næ ekki að tengjast heimaþjóni á þessari slóð, athugaðu slóðina
- réttur valkostur
Spurning eða viðfangsefni
Endurræstu forritið til að breytingin taki gildi.
Virkja LaTeX-stærðfræði
@@ -1672,10 +1671,10 @@
Settu inn tillögu
Fáðu aðstoð við að nota ${app_name}
Lagaleg atriði
- session_name:
- app_display_name:
- push_key:
- app_id:
+ Birtingarnafn setu:
+ Birtingarnafn forrits:
+ Push-lykill:
+ Auðkenni forrits:
Þú ert nú þegar að skoða þennan spjallþráð!
Þú ert nú þegar að skoða þessa spjallrás!
Útgáfa Matrix SDK
@@ -1775,7 +1774,6 @@
Þú ert núna ekki að nota neinn auðkennisþjón. Til að uppgötva og vera finnanleg/ur fyrir félaga þína í teyminu, skaltu bæta við auðkennisþjóni hér fyrir neðan.
${app_name} krefst þess að þú setjir inn auðkennin þín til að framkvæma þessa aðgerð.
Endurauðkenning er nauðsynleg
- Yfirfarðu hvar þú sért skráð/ur inn
Nota endurheimtulykil
Athuga öryggisafritunarlykil
Þetta er ekki gildur endurheimtulykill
@@ -2263,4 +2261,125 @@
Endilega lestu í gegnum stefnur og skilmála fyrir %s
Stefnur netþjónsins
Element Matrix Services (EMS) er afkastamikil og áreiðanleg hýsingarþjónusta fyrir hraðvirk og örugg samskipti í rauntíma. Skoðaðu hvernig við förum að því á element.io/ems
-
\ No newline at end of file
+
+ - %1$d valið
+ - %1$d valið
+
+ Aðgangsteiknið þitt gefur fullan aðgang að notandaaðgangnum þínum. Ekki deila því með neinum.
+ Aðgangsteikn
+ Lauk könnun
+ Könnun
+ lauk könnun.
+ bjó til könnun.
+ sendi límmerki.
+ sendi myndskeið.
+ sendi mynd.
+ sendi talskilaboð.
+ sendi hljóðskrá.
+ sendi skrá.
+ Sem svar til
+ Breyta tengli
+ Búa til tengil
+ Tengill
+ Texti
+ Staðfesta
+ Reyna aftur
+ Engin samsvörun\?
+ Skrái þig inn
+ Tengist við tæki
+ Skanna QR-kóða
+ Ertu að skrá inn farsíma/snjalltæki\?
+ Veldu \'Skanna QR-kóða\'
+ Veldu \'Skrá inn með QR-kóða\'
+ Veldu \'Birta QR-kóða\'
+ Þessi QR-kóði er ógildur.
+ Beiðnin mistókst.
+ Skrá inn með QR-kóða
+ Skanna QR-kóða
+ 3
+ 2
+ 1
+ Aðgangur að svæðum
+ Sannreyndar setur
+ Óstaðfestar setur
+ Óvirkar setur
+ Skrá inn með QR-kóða
+ Nafn á setu
+ Endurnefna setu
+ Stýrikerfi
+ Gerð
+ Vafri
+ Slóð (URL)
+ Útgáfa
+ Heiti
+ Forrit
+ Taka á móti ýti-tilkynningum á þessu tæki.
+ Ýti-tilkynningar
+ Upplýsingar um forrit, tæki og aðgerðir.
+ Skrá út úr þessari setu
+ Fela IP-vistfang
+ Birta IP-vistfang
+ Skrá út úr öllum öðrum setum
+ Skrá út
+ Óvirkar setur
+ Ráðleggingar varðandi öryggi
+ Deiling staðsetningar í rauntíma
+ Sníðing texta
+ Tengiliður
+ Myndavél
+ Staðsetning
+ Kannanir
+ Útvörpun tals
+ Viðhengi
+ Límmerki
+ Myndasafn
+ Byrjaðu talútsendingu
+ Staðsetning í rauntíma
+ Þú hefur ekki heimildir til að deila rauntímastaðsetningum
+ Uppfært fyrir %1$s síðan
+ Virkja deilingu rauntímastaðsetninga
+ Í beinni til %1$s
+ Staðsetningu í rauntíma lauk
+ Tókst ekki að hlaða inn landakorti
+\nÞessi heimaþjónn er mögulega ekki stilltur til að birta landakort.
+ Villa við að sækja kannanir.
+ Hlaða inn fleiri könnunum
+ Birting kannana
+ Fyrri kannanir
+ Virkar kannanir
+ Lauk könnuninni.
+ %1$s eftir
+ Fara áfram um 30 sekúndur
+ Fara afturábak um 30 sekúndur
+ Hleð í biðminni…
+ Bein útsending
+ Beint
+ Birta upplýsingar um síðasta notanda
+ Yfirfarðu þetta til að tryggja að aðgangurinn þinn sé öruggur
+ Þú ert með óstaðfestar setur
+ Breytingaskrá könnunar
+ Skilaboð hér eru enda-í-enda dulrituð.
+\n
+\nÖryggi skilaboðanna þinna er tryggt og einungis þú og viðtakendurnir hafa dulritunarlyklana til að opna skilaboðin.
+ Skilaboð á þessari spjallrás eru enda-í-enda dulrituð.
+\n
+\nÖryggi skilaboðanna þinna er tryggt og einungis þú og viðtakendurnir hafa dulritunarlyklana til að opna skilaboðin.
+ Hóf talútsendingu
+ Sumir stafir eru óleyfilegir
+ Setur (╯°□°)╯︵ ┻━┻ framan við hrein textaskilaboð
+ Skanna QR-kóða
+ Ekki er enn búið að útbúa notandaaðganginn þinn. Á að hætta skráningarferlinu\?
+ Útvörpun tals
+ Virkt:
+ Auðkenni setu:
+ Tilvitnanir
+ Svara til %s
+ Breytingar
+ Það lítur út fyrir að þú sért að reyna að tengjast öðrum heimaþjóni. Viltu skrá þig út\?
+ Já, stöðva
+ Afvelja allt
+ Velja allt
+ Náði því
+ Þú endaðir talútsendingu.
+ %1$s endaði talútsendingu.
+
diff --git a/library/ui-strings/src/main/res/values-it/strings.xml b/library/ui-strings/src/main/res/values-it/strings.xml
index 729b826982..d8c81974b2 100644
--- a/library/ui-strings/src/main/res/values-it/strings.xml
+++ b/library/ui-strings/src/main/res/values-it/strings.xml
@@ -1418,8 +1418,6 @@
Accesso all\'archivio sicuro fallito
Non criptato
Criptato da un dispositivo non verificato
- Controlla dove hai fatto l\'accesso
- Verifica tutte le tue sessioni per assicurarti che il tuo account e i messaggi siano protetti
Verifica il nuovo accesso entrando nel tuo account: %1$s
Verifica manualmente con testo
Verifica accesso
@@ -2263,7 +2261,6 @@
Termina sondaggio
Ciò impedirà alle persone di poter votare e mostrerà i risultati finali del sondaggio.
Terminare questo sondaggio\?
- opzione vincente
Termina sondaggio
- Risultato finale basato su %1$d voto
@@ -2704,9 +2701,6 @@
\n
\nIn questo modo hanno la certezza che stanno parlando davvero con te, ma significa anche che possono vedere il nome della sessione che inserisci qui.
Rinominare le sessioni
- Le sessioni verificate hanno effettuato l\'accesso con le tue credenziali e sono state verificate, usando la frase di sicurezza o la verifica incrociata.
-\n
-\nCiò significa che hanno le tue chiavi di crittografia per i messaggi passati, e confermano agli altri utenti con cui comunichi che queste sessioni sono usate da te.
Sessioni verificate
Le sessioni non verificate sono quelle in cui è stato fatto l\'accesso con le tue credenziali, ma che non sono state verificate.
\n
@@ -2805,7 +2799,7 @@
L\'altro dispositivo ha già fatto l\'accesso.
Si è verificato un problema di sicurezza configurando i messaggi sicuri. Una delle seguenti cose potrebbe essere compromessa: il tuo homeserver; la/e connessione/i internet; il/i dispositivo/i;
La richiesta è fallita.
- Buffer…
+ Buffer…
Sospendi trasmissione vocale
Avvia o riprendi trasmissione vocale
Ferma registrazione trasmissione vocale
@@ -2890,4 +2884,29 @@
In questa stanza non ci sono sondaggi attivi
Sondaggi attivi
Cronologia sondaggi
-
\ No newline at end of file
+ Sondaggio terminato
+ Sondaggio
+ terminato un sondaggio.
+ Sondaggio terminato.
+ Il tuo homeserver non supporta ancora l\'elenco di conversazioni.
+ A causa di errori di decifrazione, alcuni voti potrebbero non venire contati
+ Impossibile avviare questa trasmissione vocale.
+ Iniziata una trasmissione vocale
+ Errore di recupero dei sondaggi.
+ Carica più sondaggi
+ Visualizzazione sondaggi
+
+ - Non ci sono sondaggi passati nell\'ultimo giorno.
+\nCarica più sondaggi per vedere quelli dei giorni precedenti.
+ - Non ci sono sondaggi passati negli ultimi %1$d giorni.
+\nCarica più sondaggi per vedere quelli dei giorni precedenti.
+
+
+ - Non ci sono sondaggi attivi nell\'ultimo giorno.
+\nCarica più sondaggi per vedere quelli dei giorni precedenti.
+ - Non ci sono sondaggi attivi negli ultimi %1$d giorni.
+\nCarica più sondaggi per vedere quelli dei giorni precedenti.
+
+ Non puoi iniziare un messaggio vocale perché stai registrando una trasmissione in diretta. Termina la trasmissione per potere iniziare un messaggio vocale
+ Impossibile iniziare il messaggio vocale
+
diff --git a/library/ui-strings/src/main/res/values-iw/strings.xml b/library/ui-strings/src/main/res/values-iw/strings.xml
index b9f81ae446..aabdc7371e 100644
--- a/library/ui-strings/src/main/res/values-iw/strings.xml
+++ b/library/ui-strings/src/main/res/values-iw/strings.xml
@@ -1672,8 +1672,6 @@
אמת ידנית באמצעות טקסט
אמת את הכניסה החדשה שניגשת לחשבונך: %1$s
- אמת את כל ההפעלות שלך כדי להבטיח שהחשבון וההודעות שלך בטוחים
- בדוק היכן נכנסת
מוצפן על ידי מכשיר לא מאומת
לא מוצפן
שולח שלג ❄️
@@ -2136,7 +2134,6 @@
סוף המשאל
פעולה זו תעצור את האפשרות להצביע ותציג את תוצאות המשאל.
סוף המשאל\?
- אפשרות הזוכה
סוף המשאל
שאלה לא יכולה להיות ריקה
צור משאל
@@ -2506,4 +2503,4 @@
\nזה יהיה מעבר חד פעמי שכן שרשורים הם כעת חלק ממפרט Matrix.
שיתוף מסך של ${app_name}
המסך משותף כרגע
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-ja/strings.xml b/library/ui-strings/src/main/res/values-ja/strings.xml
index 11ab6ee857..d893156f6e 100644
--- a/library/ui-strings/src/main/res/values-ja/strings.xml
+++ b/library/ui-strings/src/main/res/values-ja/strings.xml
@@ -139,8 +139,8 @@
メールアドレスを追加
電話番号を追加
通知音
- このアカウントでは通知を有効にする
- このセッションでは通知を有効にする
+ このアカウントで通知を有効にする
+ このセッションで通知を有効にする
1対1のチャットでのメッセージ
グループチャットでのメッセージ
ルームへ招待されたとき
@@ -526,7 +526,7 @@
暗号化を有効にする
いったん有効にすると、暗号化を無効にすることはできません。
セキュリティー
- 詳しく知る
+ 詳細を表示
その他の設定
管理者としての操作
ルームの設定
@@ -1252,7 +1252,7 @@
Element Matrix Servicesに接続
Matrix IDでサインイン
Matrix IDでサインイン
- 詳しく知る
+ 詳細を表示
その他
カスタムと高度な設定
組織向けのプレミアムホスティング
@@ -1845,8 +1845,8 @@
- %1$d個の投票があります。結果を見るには投票してください
未認証の端末で暗号化
- メッセージを紙吹雪と共に送る
- メッセージを降雪と共に送る
+ メッセージを紙吹雪と共に送信
+ メッセージを降雪と共に送信
紙吹雪🎉を送る
降雪❄️を送る
あなたのチームのメッセージングに。
@@ -1930,7 +1930,6 @@
非公開で招待が必要なルームは表示されていません。
\nルームを追加する権限はありません。
非公開で招待が必要なルームは表示されていません。
- 勝者
知人に見つけてもらえるように電話番号を設定できます。任意です。
メッセージキー
復旧用のパスフレーズ
@@ -2223,8 +2222,6 @@
指紋や顔画像など、端末に固有の生体認証を有効にする。
絵文字で認証
テキストで認証
- すべてのセッションを認証し、アカウントとメッセージが安全であることを確認してください
- ログインしている場所を確認
復旧用の手段を全て無くしてしまいましたか?全てリセットする
クロス署名に対応した他のMatrixのクライアントでも使用できます。
どのような議論を%sで行いたいですか?
@@ -2443,7 +2440,7 @@
レイアウトの設定
了解
次へ
- 詳しく知る
+ 詳細を表示
秒
分
時
@@ -2473,4 +2470,21 @@
QRコードをスキャン
QRコードをスキャン
QRコードが不正です。
-
\ No newline at end of file
+ スペースは、ルームと連絡先をまとめる新しい方法です。はじめに、スペースを作成しましょう。
+ 最近の履歴を表示
+ この暗号化されたメッセージの信頼性はこの端末では保証できません。
+ アカウントが安全かどうか確認してください
+ 未認証のセッションがあります
+ 連絡先
+ お気に入り
+ 未読あり
+ 全て
+ はい、停止
+ 全ての選択を解除
+ 全て選択
+ 音声配信を終了しました。
+ %1$sが音声配信を終了しました。
+
+ - %1$dを選択しました
+
+
diff --git a/library/ui-strings/src/main/res/values-kab/strings.xml b/library/ui-strings/src/main/res/values-kab/strings.xml
index 353fb99f53..c16b5624a8 100644
--- a/library/ui-strings/src/main/res/values-kab/strings.xml
+++ b/library/ui-strings/src/main/res/values-kab/strings.xml
@@ -463,8 +463,6 @@
Senqed iman-ik•im d wiyaḍ akken ad qqimen yidiwenniyen-ik•im d iɣellsanen
Seqdec tasarut n uɛeddi
Ur yettwawgelhen ara
- Senqed ansi i d-tkecmeḍ
- Senqed akk tiqimiyin-ik·im i wakken ad tḍemneḍ amiḍan-ik·m & yiznan d iɣelsanen
Senqed s ufus s ttawil n uḍris
Azen
Sbadu
diff --git a/library/ui-strings/src/main/res/values-lo/strings.xml b/library/ui-strings/src/main/res/values-lo/strings.xml
index a92adb0225..715f2894ef 100644
--- a/library/ui-strings/src/main/res/values-lo/strings.xml
+++ b/library/ui-strings/src/main/res/values-lo/strings.xml
@@ -1634,8 +1634,6 @@
ຢືນຢັນການເຂົ້າສູ່ລະບົບ
ຢືນຢັນຂໍ້ຄວາມດ້ວຍຕົນເອງ
ຢືນຢັນການເຂົ້າສູ່ລະບົບໃໝ່ທີ່ເຂົ້າເຖິງບັນຊີຂອງທ່ານ: %1$s
- ຢັ້ງຢືນທຸກລະບົບຂອງທ່ານເພື່ອໃຫ້ແນ່ໃຈວ່າບັນຊີ ແລະ ຂໍ້ຄວາມຂອງທ່ານປອດໄພ
- ກວດເບິ່ງບ່ອນທີ່ທ່ານເຂົ້າສູ່ລະບົບ
ເຂົ້າລະຫັດໂດຍອຸປະກອນທີ່ບໍ່ໄດ້ຮັບການຢືນຢັນ
ບໍ່ໄດ້ເຂົ້າລະຫັດ
ສົ່ງຫິມະຕົກ ❄️
@@ -2371,7 +2369,6 @@
ສິ້ນສຸດແບບສຳຫຼວດ
ອັນນີ້ຈະຢຸດບໍ່ໃຫ້ຜູ້ຄົນສາມາດລົງຄະແນນສຽງໄດ້ ແລະຈະສະແດງຜົນສຸດທ້າຍຂອງການສຳຫຼວດຄວາມຄິດເຫັນ.
ສິ້ນສຸດແບບສຳຫຼວດນີ້ບໍ\?
- ເລືອກຜູ້ຊະນະ
ສິ້ນສຸດແບບສຳຫຼວດ
- ຜົນສຸດທ້າຍໂດຍອີງໃສ່ %1$d ຄະແນນສຽງ
diff --git a/library/ui-strings/src/main/res/values-lt/strings.xml b/library/ui-strings/src/main/res/values-lt/strings.xml
index aeba3d53e6..7ad901a9d2 100644
--- a/library/ui-strings/src/main/res/values-lt/strings.xml
+++ b/library/ui-strings/src/main/res/values-lt/strings.xml
@@ -1324,7 +1324,6 @@
Apklausa baigėsi
Prabalsuota
Baigti apklausą
- laimėtojo parinktis
Rezultatai bus matomi pasibaigus apklausai
Nėra balsų
Iš naujo paleiskite programą, kad pakeitimas įsigaliotų.
@@ -2183,4 +2182,4 @@
Įjungti atidėtas AŽ
Supaprastintas Element su nebūtinais skirtukais
Įjungti naują išdėstymą
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-lv/strings.xml b/library/ui-strings/src/main/res/values-lv/strings.xml
index 1787653fae..9201bf146a 100644
--- a/library/ui-strings/src/main/res/values-lv/strings.xml
+++ b/library/ui-strings/src/main/res/values-lv/strings.xml
@@ -559,8 +559,6 @@ Nākotnē šī pārbaudes procedūra plānota sarežģītāka.
Uzaicināt lietotājus
Apstipriniet savu identitāti, verificējot šo pierakstīšanos no kādas citas savas sesijas, tādējādi ļaujot piekļūt šifrētajām ziņām.
Manuāli verificēt ar tekstu
- Verificējiet visas savas sesijas, lai nodrošinātos, ka jūsu konts un ziņas ir drošībā
- Pārskatiet savas pierakstīšanās
Nešifrēts
vai kādu citu Matrix lietotni ar cross-signing atbalstu
Šis konts ir deaktivizēts.
diff --git a/library/ui-strings/src/main/res/values-nb-rNO/strings.xml b/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
index 067dbbbc28..13a4400c31 100644
--- a/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
+++ b/library/ui-strings/src/main/res/values-nb-rNO/strings.xml
@@ -1001,8 +1001,6 @@
Hvis du tilbakestiller alt
Du starter på nytt uten historikk, ingen meldinger, pålitelige enheter eller pålitelige brukere
Kryptert av en ubekreftet enhet
- Gjennomgå hvor du er logget inn
- Bekreft alle øktene dine for å sikre at kontoen og meldingene dine er trygge
Bekreft den nye påloggingen som får tilgang til kontoen din: %1$s
Bekreft pålogging
Bekreft identiteten din ved å bekrefte denne påloggingen fra en av de andre øktene dine, og gi den tilgang til krypterte meldinger.
@@ -1253,4 +1251,4 @@
%1$s endret visningsnavnet sitt til %2$s
%1$s utestengte %2$s
%ss invitasjon
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-nl/strings.xml b/library/ui-strings/src/main/res/values-nl/strings.xml
index 5bc5305df4..c6154ddb45 100644
--- a/library/ui-strings/src/main/res/values-nl/strings.xml
+++ b/library/ui-strings/src/main/res/values-nl/strings.xml
@@ -1858,8 +1858,6 @@
Interactief verifiëren door Emoji
Handmatig verifiëren via tekst
Verifieer de nieuwe login voor toegang tot je account: %1$s
- Verifieer al je sessies om ervoor te zorgen dat je account en berichten veilig zijn
- Bekijk waar je bent ingelogd
Versleuteld door een niet-geverifieerd apparaat
stuurt sneeuwval ❄️
stuurt confetti 🎉
@@ -2186,7 +2184,6 @@
Einde poll
Hierdoor kunnen mensen niet meer stemmen en worden de definitieve resultaten van de poll weergegeven.
Deze poll beëindigen\?
- winnaar optie
Einde poll
- Eindresultaat gebaseerd op %1$d stem
@@ -2746,7 +2743,7 @@
Deze sessie is klaar voor veilige communicatie.
Je huidige sessie is klaar voor veilige communicatie.
Onbekende verificatiestatus
- Bufferen
+ Bufferen
Live
De authenticiteit van dit versleutelde bericht kan niet worden gegarandeerd op dit apparaat.
Incognito toetsenbord
@@ -2787,9 +2784,6 @@
\n
\nDit geeft ze het vertrouwen dat ze echt met jou praten, maar het betekent ook dat ze de sessienaam kunnen zien die je hier invoert.
Sessies hernoemen
- Geverifieerde sessies zijn ingelogd met jouw inloggegevens en vervolgens geverifieerd, hetzij met je veilige wachtwoordzin of door kruisverificatie.
-\n
-\nDit betekent dat ze coderingssleutels bevatten voor je eerdere berichten en bevestigen aan andere gebruikers waarmee je communiceert dat deze sessies echt van jou zijn.
Niet-geverifieerde sessies zijn sessies die zijn aangemeld met jouw inloggegevens, maar niet zijn geverifieerd.
\n
\nJe moet er vooral zeker van zijn dat je deze sessies herkent, omdat ze een ongeoorloofd gebruik van je account kunnen vertegenwoordigen.
@@ -2842,4 +2836,4 @@
Bewerking
Recente gesprekken in het deelmenu van het systeem tonen
Direct delen inschakelen
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-pl/strings.xml b/library/ui-strings/src/main/res/values-pl/strings.xml
index 4b26562b06..0aad400340 100644
--- a/library/ui-strings/src/main/res/values-pl/strings.xml
+++ b/library/ui-strings/src/main/res/values-pl/strings.xml
@@ -665,7 +665,7 @@
Wycisz
Ustawienia
Nie ignorujesz żadnych użytkowników
- Widziany przez
+ Wyświetlono przez
Zaawansowane ustawienia
Tryb programisty
Ustawienia
@@ -1553,8 +1553,6 @@
Interaktywna weryfikacja z wykorzystaniem emotikon
Zweryfikuj logowanie
Zweryfikuj nowe logowanie do swojego konta: %1$s
- Sprawdź wszystkie swoje sesje żeby upewnić się, że Twoje konto oraz wiadomości są bezpieczne
- Sprawdź gdzie jesteś zalogowany(-na)
Zaszyfrowane przez niezweryfikowane urządzenie
Niezaszyfrowane
@@ -2514,7 +2512,6 @@
Otwarta ankieta
Rodzaj ankiety
Modyfikacja ankiety
- opcja zwyciężająca
Brak głosów
Zaproszenie do tej przestrzeni zostało wysłane do %s, które nie jest powiązane z Twoim kontem
Zaproszenie do tego pokoju zostało wysłane do %s, które nie jest powiązane z Twoim kontem
@@ -2798,4 +2795,4 @@
Rozumiem
Zwiń %s pokojów
Rozwiń %s pokojów
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-pt-rBR/strings.xml b/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
index a5aa778156..f6a2c94553 100644
--- a/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
+++ b/library/ui-strings/src/main/res/values-pt-rBR/strings.xml
@@ -1526,8 +1526,6 @@
Falha para acessar armazenamento seguro
Não-encripada
Encriptada por um dispositivo não-verificado
- Revisar onde você está com login feito
- Verifique todas as suas sessões para assegurar que sua conta & mensagens estão seguras
Verifique o novo login acessando sua conta: %1$s
Verificar Manualmente por Texto
Verificar login
@@ -2272,7 +2270,6 @@
Terminar sondagem
Isto vai parar pessoas de serem capazes de votar e vai exibir os resultados finais da sondagem.
Terminar esta sondagem\?
- opção vencedora
Terminar sondagem
- Resultado final baseado em %1$d voto
@@ -2713,9 +2710,6 @@
\n
\nIsto as/os provê com confiança que elas(es) são estão realmente falando com você, mas também significa que elas(es) veem o nome da sessão que você entrar aqui.
Renomeando sessões
- Sessões verificadas têm feito login com suas credenciais e então têm sido verificadas, ou usando sua frasepasse segura ou por verificação cruzada.
-\n
-\nIsto significa que elas mantêm chaves de encriptação para suas mensagens anteriores, e confirmam a outras(os) usuárias(os) com quem você está comunicando que estas sessões são realmente você.
Sessões verificadas
Sessões não-verificadas são sessões que você tem feito login com suas credenciais mas não têm sido verificadas cruzado.
\n
@@ -2814,7 +2808,7 @@
A requisição falhou.
Seja capaz de gravar e enviar broadcast de voz em timeline de sala.
Broadcast de voz
- Buffering…
+ Buffering…
Pausar broadcast de voz
Tocar ou retomar broadcast de voz
Parar gravação de broadcast de voz
@@ -2890,4 +2884,4 @@
Tem certeza que você quer parar seu broadcast ao vivo\? Isto vai terminar o broadcast e a gravação completa vai estar disponível na sala.
Parar de fazer broadcasting ao vivo\?
Sim, Parar
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-ru/strings.xml b/library/ui-strings/src/main/res/values-ru/strings.xml
index 0d8f1103fe..1255776c1f 100644
--- a/library/ui-strings/src/main/res/values-ru/strings.xml
+++ b/library/ui-strings/src/main/res/values-ru/strings.xml
@@ -1577,8 +1577,6 @@
Не удалось получить доступ к защищенному хранилищу данных
Не зашифровано
Зашифровано неподтверждённой сессией
- Посмотрите, где вы вошли
- Подтвердите все свои сессии, чтобы убедиться в безопасности вашей учетной записи и сообщений
Ручная проверка с помощью текста
Перепроверьте эту ссылку
Ссылка %1$s перенаправит вас на другой сайт: %2$s.
@@ -2332,7 +2330,6 @@
Завершить опрос
Это лишит людей возможности голосовать и отобразит окончательные результаты опроса.
Завершить этот опрос\?
- вариант-победитель
Завершить опрос
- Окончательный результат на основании %1$d голоса
@@ -2882,9 +2879,6 @@
Заверенные сеансы есть везде, где вы используете эту учётную запись после ввода своей мнемонической фразы или подтверждения своей личности с помощью другого заверенного сеанса.
\n
\nЭто означает, что у вас есть все ключи, необходимые для разблокировки ваших зашифрованных сообщений и подтверждения другим пользователям, что вы доверяете этому сеансу.
- Заверенные сеансы — сеансы, которые вошли в систему с вашими учётными данными, а затем были заверены либо мнемонической фразой (бумажным ключом), либо путём перекрёстной сверки.
-\n
-\nЭто означает, что они хранят ключи шифрования от ваших предыдущих сообщений и подтверждают другим пользователям, с которыми вы общаетесь, что эти сеансы — действительно ваши.
Незаверенные сеансы — это сеансы, которые вошли в систему с вашими учётными данными, но не были перекрёстно заверены.
\n
\nВы должны быть особенно уверены, что признаёте эти сеансы, поскольку они могут представлять собой несанкционированное использование вашей учётной записи.
@@ -2921,7 +2915,7 @@
Не получилось начать новую голосовую трансляцию
Перемотать вперёд на 30 секунд
Перемотать назад на 30 секунд
- Буферизация…
+ Буферизация…
Приостановить голосовую трансляцию
Проиграть или продолжить голосовую трансляцию
Остановить запись голосовой трансляции
@@ -2976,4 +2970,4 @@
Этот сеанс не поддерживает шифрование и поэтому не может быть заверен.
%1$s завершил(а) голосовую трансляцию.
Вы завершили голосовую трансляцию.
-
\ No newline at end of file
+
diff --git a/library/ui-strings/src/main/res/values-sk/strings.xml b/library/ui-strings/src/main/res/values-sk/strings.xml
index 34155ba6a5..ed3f47f9d3 100644
--- a/library/ui-strings/src/main/res/values-sk/strings.xml
+++ b/library/ui-strings/src/main/res/values-sk/strings.xml
@@ -2001,8 +2001,6 @@
Interaktívne overte pomocou emotikonov
Manuálne overte pomocou textu
Overte nové prihlásenie s prístupom k vášmu účtu: %1$s
- Overte všetky vaše relácie, aby ste si boli istý, že sú vaše správy a účet bezpečné
- Skontrolujte, kde ste prihlásení
Šifrované neovereným zariadením
pošle sneženie ❄️
pošle konfety 🎉
@@ -2421,7 +2419,6 @@
Pokračovať pomocou jednotného prihlásenia SSO
jednotné prihlásenie SSO
Zatvoriť výzvu na zálohovanie kľúčov
- Výťazná odpoveď
Nezaškrtnuté
Zaškrtnuté
Rozpísaná správa
@@ -2767,9 +2764,6 @@
\n
\nTo im poskytuje istotu, že sa komunikujú naozaj s vami, ale zároveň to znamená, že vidia názov relácie, ktorý sem zadáte.
Premenovanie relácií
- Overené relácie, do ktorých ste sa prihlásili pomocou svojich prihlasovacích údajov a ktoré boli následne overené buď pomocou vašej bezpečnostnej prístupovej frázy, alebo krížovým overením.
-\n
-\nTo znamená, že majú šifrovacie kľúče pre vaše predchádzajúce správy a potvrdzujú ostatným používateľom, s ktorými komunikujete, že tieto relácie ste skutočne vy.
Overené relácie
Neoverené relácie sú relácie, do ktorých ste sa prihlásili pomocou svojich prístupových údajov, ale ktoré neboli krížovo overené.
\n
@@ -2868,7 +2862,7 @@
Žiadosť zlyhala.
Možnosť nahrávania a odosielania hlasového vysielania v časovej osi miestnosti.
Zapnúť hlasové vysielanie
- Načítavanie do vyrovnávacej pamäte…
+ Načítavanie do vyrovnávacej pamäte…
Pozastaviť hlasové vysielanie
Prehrať alebo pokračovať v nahrávaní hlasového vysielania
Zastaviť nahrávanie hlasového vysielania
@@ -2955,4 +2949,33 @@
V tejto miestnosti nie sú žiadne aktívne ankety
Aktívne ankety
História ankety
-
\ No newline at end of file
+ Ukončená anketa
+ Anketa
+ ukončil/a anketu.
+ Ukončil/a anketu.
+ Váš domovský server zatiaľ nepodporuje zobrazovanie vlákien.
+ Toto hlasové vysielanie nie je možné prehrať.
+ Spustil/a hlasové vysielanie
+ Z dôvodu chýb v dešifrovaní sa niektoré hlasy nemusia započítať
+ Chyba pri načítavaní ankiet.
+ Načítať ďalšie ankety
+ Zobrazenie ankiet
+
+ - Za uplynulý deň nie sú k dispozícii žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+ - Za posledné %1$d dni nie sú aktívne žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+ - Za posledných %1$d dní nie sú aktívne žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+
+
+ - Za posledný deň nie sú aktívne žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+ - Za posledných %1$d dni nie sú aktívne žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+ - Za posledných %1$d dní nie sú aktívne žiadne ankety.
+\nNačítaním ďalších ankiet zobrazíte ankety za predchádzajúce dni.
+
+ Nemôžete spustiť hlasovú správu, pretože práve nahrávate živé vysielanie. Ukončite prosím živé vysielanie, aby ste mohli začať nahrávať hlasovú správu
+ Nemožno spustiť hlasovú správu
+
diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml
index c3f9d53c99..374080cb23 100644
--- a/library/ui-strings/src/main/res/values-sq/strings.xml
+++ b/library/ui-strings/src/main/res/values-sq/strings.xml
@@ -1413,8 +1413,6 @@
S’u arrit të hyhet në depozitë të sigurt
Të pafshehtëzuara
Fshehtëzuar nga një pajisje e paverifikuar
- Shqyrtojini kur të jeni i futur
- Verifikoni krejt sesionet tuaj që të siguroheni se llogaria & mesazhet tuaja janë të sigurt
Verifikoni kredencialet e reja për hyrje te llogaria juaj: %1$s
Verifikojeni Dorazi përmes Teksti
Verifikoni kredenciale hyrjeje
@@ -2512,9 +2510,6 @@
\n
\nKjo u jep atyre besim se po flasin vërtet me ju, por do të thotë gjithashtu që mund shohin emrin e sesionit që jepni këtu.
Riemërtim sesionesh
- Sesionet e verifikuar përfaqësojnë sesione ku është bërë hyrja dhe janë verifikuar, ose duke përdorur togfjalëshin tuaj të sigurt, ose me verifikim.
-\n
-\nKjo do të thotë se zotërojnë kyçe fshehtëzimi për mesazhe tuajt të mëparshëm dhe u ripohojnë përdoruesve të tjerë, me të cilët po komunikoni, se këto sesione ju takojnë juve.
Sesione të verifikuar
Sesionet e paverifikuar janë sesione në të cilët është bërë hyrja me kredencialet tuaja, por pa u bërë verifikim.
\n
@@ -2659,7 +2654,7 @@
\nKy shërbyes Home mund të mos jetë formësuar të shfaqë harta.
Përfundimet do të jenë të dukshme pasi të ketë përfunduar pyetësori
Kur bëhet ftesë në një dhomë të fshehtëzuar që ka historik ndarjesh me të tjerët, historiku i fshehtëzuar do të jetë i dukshëm.
-
+
Ndal transmetim zanor
Luani ose vazhdoni luajtje transmetimi zanor
Ndal incizim transmetimi zanor
@@ -2876,10 +2871,20 @@
Tekst
Tokeni juaj i hyrjeve jep hyrje të plotë në llogarinë tuaj. Mos ia jepni kujt.
Token Hyrjesh
- S’ka pyetësorë të kaluar në këtë dhomë
- Pyetësorë të kaluar
+ Në këtë dhomë s’ka pyetësorë të dikurshëm
+ Pyetësorë të dikurshëm
S’ka pyetësorë aktivë në këtë dhomë
Pyetësorë aktivë
- mundësia fituese
Historik pyetësorësh
-
\ No newline at end of file
+ Përfundoi pyetësorin
+ Përfundoi pyetësorin.
+ Pyetësor
+ përfundoi një pyetësor.
+ Shfaq/fshi listë me toptha
+ Shfaq/fshi listë të numërtuar
+ Ujdisni lidhje
+ Për shkak gabimesh shfshehtëzimi, mund të mos jenë numëruar disa vota
+ S’arrihet të luhet ky transmetim zanor.
+ Nisni një transmetim zanor
+ Shërbyesi juaj Home s’mbulon ende paraqitje rrjedhash.
+
diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml
index 373165802a..877a95f2de 100644
--- a/library/ui-strings/src/main/res/values-sv/strings.xml
+++ b/library/ui-strings/src/main/res/values-sv/strings.xml
@@ -662,8 +662,6 @@
Kryptering inte aktiverat
Aviseringskonfiguration
Meddelanden som innehåller @room
- Granska var du är inloggad
- Verifiera alla dina sessioner för att se till att ditt konto och dina meddelanden är säkra
Vi kunde inte skapa ditt DM. Vänligen kolla användarna du vill bjuda in och försök igen.
BJUD IN
Bjud in användare
@@ -2281,7 +2279,6 @@
Avsluta omröstningen
Det här kommer att stoppa personer från att rösta och visa det slutgiltiga resultatet av omröstningen.
Avsluta den här omröstningen\?
- vinnande alternativ
Avsluta omröstning
- Slutgiltigt resultat baserat på %1$d röst
@@ -2737,9 +2734,6 @@
\n
\nDet försäkrar dem om att de verkligen pratar med dig, men det betyder också att de kan se sessionsnamnet du anger här.
Döper om sessioner
- Verifierade sessioner har loggat in med dina uppgifter och har sedan verifierats, antingen med din säkra lösenfras eller genom att kors-verifiera.
-\n
-\nDet betyder att det har krypteringsnycklar för dina tidigare meddelanden, bekräftar för andra användare du kommunicerar med att dessa sessioner verkligen är du.
Verifierade sessioner
Overifierade sessioner är sessioner som har loggat in med dina uppgifter men som inte har kors-verifierats.
\n
@@ -2804,7 +2798,7 @@
Använd din inloggade enhet för att skanna QR-koden nedan:
Logga in med QR-kod
Använd den här enhetens kamera för att skanna QR-koden på din andra enhet:
- Buffrar…
+ Buffrar…
Pausa röstsändning
Spela eller återuppta röstsändning
Avsluta inspelning av röstsändning
@@ -2882,4 +2876,26 @@
Direktsändning
Du avslutade en röstsändning.
%1$s avslutade en röstsändning.
-
\ No newline at end of file
+ Din åtkomsttoken ger full åtkomst till ditt konto. Dela den inte med någon.
+ Åtkomsttoken
+ Avslutade omröstning
+ Omröstning
+ avslutade en omröstning.
+ Redigera länk
+ Skapa en länk
+ Länk
+ Text
+ Växla punktlista
+ Växla numrerad lista
+ Sätt länk
+ Det finns inga tidigare omröstningar i det här rummet
+ Tidigare omröstningar
+ Det finns inga aktiva omröstningar i det här rummet
+ Aktiva omröstningar
+ Avslutade omröstningen.
+ Är du säker på att du vill avsluta din direktsändning\? Detta kommer att avsluta sändningen och den fulla inspelningen kommer att bli tillgänglig i rummet.
+ Avsluta röstsändning\?
+ Omröstningshistorik
+ Din hemserver har inte stöd för att lista trådar än.
+ Ja, sluta
+
diff --git a/library/ui-strings/src/main/res/values-sw/strings.xml b/library/ui-strings/src/main/res/values-sw/strings.xml
new file mode 100644
index 0000000000..d1938c5896
--- /dev/null
+++ b/library/ui-strings/src/main/res/values-sw/strings.xml
@@ -0,0 +1,14 @@
+
+
+ umeondoa %1$s
+ %1$s kuondolewa %2$s
+ Ulikataa mwaliko
+ %1$s alikataa mwaliko
+ Ulijiunga
+ %1$s alijiunga
+ %1$s Amekualika
+
+ - %1$d Iliyochaguliwa
+ - %1$d Ziliyochaguliwa
+
+
diff --git a/library/ui-strings/src/main/res/values-uk/strings.xml b/library/ui-strings/src/main/res/values-uk/strings.xml
index 2ee9685c76..6294526be2 100644
--- a/library/ui-strings/src/main/res/values-uk/strings.xml
+++ b/library/ui-strings/src/main/res/values-uk/strings.xml
@@ -1156,7 +1156,6 @@
Довірений
Не довірений вхід
Підтвердьте особу, звіривши цей вхід своїм іншим сеансом і надавши йому доступ до зашифрованих повідомлень.
- Звірте усі свої сеанси, щоб переконатись у безпечності вашого облікового запису та повідомлень
Сеанси
Не вдалось отримати сеанси
Ви не маєте доступу до цього повідомлення, бо відправник не довіряє вашому сеансу
@@ -2012,7 +2011,6 @@
Додати людей
Додати учасників
Перевірте це посилання
- Перевірте, де ви ввійшли
Інтерактивна перевірка за допомогою емоджі
Виберіть пароль.
Виберіть ім\'я користувача.
@@ -2360,7 +2358,6 @@
Завершити опитування
Люди більше не зможуть голосувати, і будуть показані остаточні результати опитування.
Завершити це опитування\?
- варіант-переможець
Завершити опитування
- Остаточний результат на підставі %1$d голосу
@@ -2821,9 +2818,6 @@
\n
\nЦе дає їм впевненість у тому, що вони дійсно розмовляють з вами, а також означає, що вони можуть бачити назву сеансу, яку ви ввели тут.
Перейменування сеансів
- Звірені сеанси — ті, до яких ви ввійшли за допомогою своїх облікових даних, а потім пройшли перевірку, використовуючи вашу захищену парольну фразу або шляхом перехресної перевірки.
-\n
-\nЦе означає, що вони мають ключі шифрування для ваших попередніх повідомлень і підтверджують іншим користувачам, з якими ви спілкуєтеся, що ці сеанси — це дійсно ви.
Звірені сеанси
Не звірені сеанси — це сеанси, до яких ви ввійшли в за допомогою своїх облікових даних, але не пройшли перехресну перевірку.
\n
@@ -2922,7 +2916,7 @@
Запит не виконаний.
Можливість записувати та надсилати голосові трансляції до стрічки кімнати.
Увімкнути голосові трансляції
- Буферизація…
+ Буферизація…
Призупинити голосову трансляцію
Відтворити або поновити відтворення голосової трансляції
Припинити запис голосової трансляції
@@ -3011,4 +3005,37 @@
У цій кімнаті немає активних опитувань
Активні опитування
Історія опитувань
-
\ No newline at end of file
+ Завершене опитування
+ Опитування
+ завершує опитування.
+ Опитування завершено.
+ Ваш домашній сервер поки що не підтримує створення списків гілок.
+ Неможливо відтворити цю голосову трансляцію.
+ Розпочато голосову трансляцію
+ Через помилки розшифрування деякі голоси можуть бути не враховані
+
+ - За %1$d минулий день немає минулих опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За минулі %1$d дні немає минулих опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За минулі %1$d днів немає минулих опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За минулі %1$d днів немає минулих опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+
+
+ - За %1$d останній день немає активних опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За останні %1$d дні немає активних опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За останні %1$d днів немає активних опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+ - За останні %1$d днів немає активних опитувань.
+\nЗавантажте більше опитувань, щоб переглянути опитування за попередні дні.
+
+ Помилка отримання опитувань.
+ Завантажити більше опитувань
+ Показ опитувань
+ Ви не можете розпочати запис голосового повідомлення, оскільки ви записуєте трансляцію наживо. Будь ласка, заверште її, щоб розпочати запис голосового повідомлення
+ Не вдалося розпочати запис голосового повідомлення
+
diff --git a/library/ui-strings/src/main/res/values-vi/strings.xml b/library/ui-strings/src/main/res/values-vi/strings.xml
index c6dc97f782..70755f1394 100644
--- a/library/ui-strings/src/main/res/values-vi/strings.xml
+++ b/library/ui-strings/src/main/res/values-vi/strings.xml
@@ -1193,7 +1193,6 @@
Kết thúc cuộc thăm dò ý kiến
Điều này sẽ ngăn mọi người có thể bỏ phiếu và sẽ hiển thị kết quả cuối cùng của cuộc thăm dò.
Kết thúc cuộc thăm dò này\?
- tùy chọn người chiến thắng
Kết thúc cuộc thăm dò ý kiến
Câu hỏi không thể trống
TẠO CUỘC THĂM DÒ Ý KIẾN
@@ -1472,8 +1471,6 @@
Xác minh đăng nhập
Xác minh thủ công bằng Văn bản
Xác minh thông tin đăng nhập mới truy cập vào tài khoản của bạn: %1$s
- Xác minh tất cả các phiên của bạn để đảm bảo tài khoản và tin nhắn của bạn được an toàn
- Xem lại nơi bạn đăng nhập
Được mã hóa bởi một thiết bị chưa được xác minh
Không được mã hóa
gửi tuyết rơi ❄️
diff --git a/library/ui-strings/src/main/res/values-zh-rCN/strings.xml b/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
index 9f975e61e4..1e75540acf 100644
--- a/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
+++ b/library/ui-strings/src/main/res/values-zh-rCN/strings.xml
@@ -1459,8 +1459,6 @@
访问安全存储失败
未加密
由未验证设备加密
- 查看你的登录位置
- 验证你的全部会话确保你的账户和消息安全
验证访问你的账户的新登录:%1$s
使用文本手动验证
验证登录
@@ -1692,8 +1690,8 @@
一些字符不被允许
请提供一个房间地址
此地址已被使用
- 你可以启用此选项如果此房间将仅用于你的主服务器上的内部团队协作。此选项之后无法更改。
- 屏蔽不是 %s 一部分的任何人加入此房间
+ 若房间仅用于与你的主服务器上的内部团队协作,则你可以启用此选项。此选项之后无法更改。
+ 阻止任何不属于%s的人加入此房间
隐藏高级
显示高级
清除历史记录
@@ -2231,7 +2229,6 @@
结束投票
这将使人们无法再投票,并将显示投票的最终结果。
结束此投票?
- 赢家选项
结束投票
- 基于 %1$d 票的最终结果
@@ -2648,9 +2645,6 @@
\n
\n这让他们确信他们真的在与你交谈,但这也意味着他们可以看到你在此处输入的会话名称。
重命名会话
- 已验证会话已使用你的凭据登录,然后使用你的安全密码或通过交叉验证进行验证。
-\n
-\n这意味着他们持有你之前消息的加密密钥,并向你正在与之通信的其他用户确认这些会话确实是你。
闲置会话是你一段时间未使用的会话,但它们会继续接收加密密钥。
\n
\n删除闲置会话可以提高安全性和性能,并使你更容易识别新会话是否可疑。
@@ -2694,7 +2688,7 @@
验证你当前的会话以显示此会话的验证状态。
未知的验证状态
开始语音广播
- 正在缓冲……
+ 正在缓冲……
暂停语音广播
实时
知道了
@@ -2821,4 +2815,8 @@
Nightly构建
你结束了一个语音广播。
%1$s结束了一个语音广播。
-
\ No newline at end of file
+ 停止实时广播?
+ 无法播放此语音广播。
+ 你无法启动语音消息因为你正在录制实时广播。请终止实时广播以开始录制语音消息
+ 无法启动语音消息
+
diff --git a/library/ui-strings/src/main/res/values-zh-rTW/strings.xml b/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
index 14729c5b44..c650a1e6b2 100644
--- a/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
+++ b/library/ui-strings/src/main/res/values-zh-rTW/strings.xml
@@ -1412,8 +1412,6 @@
我們無法建立您的直接訊息。請檢查您想要邀請的使用者,然後再試一次。
未加密
由未驗證的裝置加密
- 審閱您從何處登入
- 驗證您所有的工作階段以確保您的帳號與訊息都安全
驗證正在存取您帳號的新登入:%1$s
%1$s:%2$s
%1$s:%2$s %3$s
@@ -2231,7 +2229,6 @@
結束投票
這將阻止人們投票並顯示投票的最終結果。
結束此投票?
- 獲勝選項
結束投票
- 以 %1$d 票為基礎的最終結果
@@ -2659,9 +2656,6 @@
\n
\n這讓他們確信他們真的在與您交談,但這也意味著他們可以看到您在此處輸入的工作階段名稱。
正在重新命名工作階段
- 已驗證的工作階段代表使用您的憑證登入,然後使用您的安全通關密語或透過交叉驗證進行驗證。
-\n
-\n這代表了它們持有您先前訊息的加密金鑰,並向您正在與之通訊的其他使用者確認這些工作階段確實是您。
已驗證的工作階段
未驗證的工作階段是使用您的憑證登入但未交叉驗證的工作階段。
\n
@@ -2760,7 +2754,7 @@
請求失敗。
可以在聊天室時間軸中錄製並傳送語音廣播。
啟用語音廣播
- 正在緩衝……
+ 正在緩衝……
暫停語音廣播
播放或繼續語音廣播
停止語音廣播錄製
@@ -2843,4 +2837,23 @@
此聊天室沒有正在進行的投票
進行中的投票
投票歷史紀錄
-
\ No newline at end of file
+ 已結束投票
+ 投票
+ 已結束投票。
+ 已結束投票。
+ 您的家伺服器還不支援列出討論串。
+ 無法播放此語音廣播。
+ 已開始語音廣播
+ 因為解密錯誤,部份投票可能並未計算
+ 擷取投票時發生錯誤。
+ 載入更多投票
+ 顯示投票
+
+ - 過去 %1$d 天沒有投票。
+\n載入更多投票以檢視過去幾天的投票。
+
+
+ - 過去 %1$d 天沒有活躍的投票。
+\n載入更多投票以檢視過去幾天的投票。
+
+
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index e156e55f11..6a9d3e583d 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -1690,7 +1690,6 @@
Create New Room
Create New Space
No network. Please check your Internet connection.
-
Something went wrong. Please check your network connection and try again.
"Change network"
"Please wait…"
@@ -2670,10 +2669,6 @@
Encrypted by an unverified device
Encrypted by a deleted device
The authenticity of this encrypted message can\'t be guaranteed on this device.
-
- Review where you’re logged in
-
- Verify all your sessions to ensure your account & messages are safe
You have unverified sessions
Review to ensure your account is safe
@@ -3122,8 +3117,7 @@
Live
Live broadcast
-
- Buffering…
+ Buffering…
Resume voice broadcast record
Pause voice broadcast record
Stop voice broadcast record
@@ -3136,6 +3130,7 @@
Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.
You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.
Unable to play this voice broadcast.
+ Connection error - Recording paused
%1$s left
Stop live broadcasting?
@@ -3193,8 +3188,6 @@
- Final result based on %1$d votes
End poll
-
- winner option
End this poll?
This will stop people from being able to vote and will display the final results of the poll.
End poll
@@ -3440,8 +3433,6 @@
Unverified sessions
Unverified sessions are sessions that have logged in with your credentials but not been cross-verified.\n\nYou should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.
Verified sessions
-
- Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.
Verified sessions are anywhere you are using this account after entering your passphrase or confirming your identity with another verified session.\n\nThis means that you have all the keys needed to unlock your encrypted messages and confirm to other users that you trust this session.
This session doesn\'t support encryption, so it can\'t be verified.\n\nYou won\'t be able to participate in rooms where encryption is enabled when using this session.\n\nFor best security and privacy, it is recommended to use Matrix clients that support encryption.
Renaming sessions
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index e74fe0a452..f378b3acc2 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -63,7 +63,7 @@ android {
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
- buildConfigField "String", "SDK_VERSION", "\"1.5.22\""
+ buildConfigField "String", "SDK_VERSION", "\"1.5.24\""
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MetricsExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MetricsExtensions.kt
index 7f0e828f62..5aa175f994 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MetricsExtensions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MetricsExtensions.kt
@@ -43,6 +43,27 @@ inline fun List.measureMetric(block: () -> Unit) {
}
}
+/**
+ * Executes the given [block] while measuring the transaction.
+ *
+ * @param block Action/Task to be executed within this span.
+ */
+@OptIn(ExperimentalContracts::class)
+inline fun List.measureSpannableMetric(block: List.() -> Unit) {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ try {
+ this.forEach { plugin -> plugin.startTransaction() } // Start the transaction.
+ block()
+ } catch (throwable: Throwable) {
+ this.forEach { plugin -> plugin.onError(throwable) } // Capture if there is any exception thrown.
+ throw throwable
+ } finally {
+ this.forEach { plugin -> plugin.finishTransaction() } // Finally, finish this transaction.
+ }
+}
+
/**
* Executes the given [block] while measuring a span.
*
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/metrics/SyncDurationMetricPlugin.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/metrics/SyncDurationMetricPlugin.kt
index 79ece002e9..e54eb3cccf 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/metrics/SyncDurationMetricPlugin.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/metrics/SyncDurationMetricPlugin.kt
@@ -29,4 +29,6 @@ interface SyncDurationMetricPlugin : SpannableMetricPlugin {
override fun logTransaction(message: String?) {
Timber.tag(loggerTag.value).v("## syncResponseHandler() : $message")
}
+
+ fun shouldReport(isInitialSync: Boolean, isAfterPause: Boolean): Boolean = true
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
index 11638837cc..96e52469c3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt
@@ -75,6 +75,11 @@ data class HomeServerCapabilities(
* True if the home server supports remote toggle of Pusher for a given device.
*/
val canRemotelyTogglePushNotificationsOfDevices: Boolean = false,
+
+ /**
+ * True if the home server supports event redaction with relations.
+ */
+ var canRedactEventWithRelations: Boolean = false,
) {
enum class RoomCapabilitySupport {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
index 6a6fadc95a..07036f4b65 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt
@@ -156,11 +156,12 @@ interface SendService {
/**
* Redact (delete) the given event.
- * @param event The event to redact
- * @param reason Optional reason string
+ * @param event the event to redact
+ * @param reason optional reason string
+ * @param withRelations the list of relation types to redact with this event
* @param additionalContent additional content to put in the event content
*/
- fun redactEvent(event: Event, reason: String?, additionalContent: Content? = null): Cancelable
+ fun redactEvent(event: Event, reason: String?, withRelations: List? = null, additionalContent: Content? = null): Cancelable
/**
* Schedule this message to be resent.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt
index f4de6a9ae9..4d8e90cf35 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/version/Versions.kt
@@ -58,6 +58,8 @@ private const val FEATURE_QR_CODE_LOGIN = "org.matrix.msc3882"
private const val FEATURE_THREADS_MSC3771 = "org.matrix.msc3771"
private const val FEATURE_THREADS_MSC3773 = "org.matrix.msc3773"
private const val FEATURE_REMOTE_TOGGLE_PUSH_NOTIFICATIONS_MSC3881 = "org.matrix.msc3881"
+private const val FEATURE_EVENT_REDACTION_WITH_RELATIONS = "org.matrix.msc3912"
+private const val FEATURE_EVENT_REDACTION_WITH_RELATIONS_STABLE = "org.matrix.msc3912.stable"
/**
* Return true if the SDK supports this homeserver version.
@@ -153,3 +155,13 @@ private fun Versions.getMaxVersion(): HomeServerVersion {
internal fun Versions.doesServerSupportRemoteToggleOfPushNotifications(): Boolean {
return unstableFeatures?.get(FEATURE_REMOTE_TOGGLE_PUSH_NOTIFICATIONS_MSC3881).orFalse()
}
+
+/**
+ * Indicate if the server supports MSC3912: https://github.com/matrix-org/matrix-spec-proposals/pull/3912.
+ *
+ * @return true if event redaction with relations is supported
+ */
+internal fun Versions.doesServerSupportRedactEventWithRelations(): Boolean {
+ return unstableFeatures?.get(FEATURE_EVENT_REDACTION_WITH_RELATIONS).orFalse() ||
+ unstableFeatures?.get(FEATURE_EVENT_REDACTION_WITH_RELATIONS_STABLE).orFalse()
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/RedactEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/RedactEventTask.kt
index 56bdc8cae8..b060748a61 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/RedactEventTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/RedactEventTask.kt
@@ -15,9 +15,12 @@
*/
package org.matrix.android.sdk.internal.crypto.tasks
+import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.session.homeserver.HomeServerCapabilitiesDataSource
import org.matrix.android.sdk.internal.session.room.RoomAPI
+import org.matrix.android.sdk.internal.session.room.send.model.EventRedactBody
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
@@ -26,22 +29,34 @@ internal interface RedactEventTask : Task {
val txID: String,
val roomId: String,
val eventId: String,
- val reason: String?
+ val reason: String?,
+ val withRelations: List?,
)
}
internal class DefaultRedactEventTask @Inject constructor(
private val roomAPI: RoomAPI,
- private val globalErrorReceiver: GlobalErrorReceiver
+ private val globalErrorReceiver: GlobalErrorReceiver,
+ private val homeServerCapabilitiesDataSource: HomeServerCapabilitiesDataSource,
) : RedactEventTask {
override suspend fun execute(params: RedactEventTask.Params): String {
+ val withRelations = if (homeServerCapabilitiesDataSource.getHomeServerCapabilities()?.canRedactEventWithRelations.orFalse() &&
+ !params.withRelations.isNullOrEmpty()) {
+ params.withRelations
+ } else {
+ null
+ }
+
val response = executeRequest(globalErrorReceiver) {
roomAPI.redactEvent(
txId = params.txID,
roomId = params.roomId,
eventId = params.eventId,
- reason = if (params.reason == null) emptyMap() else mapOf("reason" to params.reason)
+ body = EventRedactBody(
+ reason = params.reason,
+ withRelations = withRelations,
+ )
)
}
return response.eventId
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
index 2b7e9a04a1..fe55beb997 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt
@@ -65,6 +65,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo045
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo046
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo047
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo048
+import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo049
import org.matrix.android.sdk.internal.util.Normalizer
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
import javax.inject.Inject
@@ -73,7 +74,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
private val normalizer: Normalizer
) : MatrixRealmMigration(
dbName = "Session",
- schemaVersion = 48L,
+ schemaVersion = 49L,
) {
/**
* Forces all RealmSessionStoreMigration instances to be equal.
@@ -131,5 +132,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldVersion < 46) MigrateSessionTo046(realm).perform()
if (oldVersion < 47) MigrateSessionTo047(realm).perform()
if (oldVersion < 48) MigrateSessionTo048(realm).perform()
+ if (oldVersion < 49) MigrateSessionTo049(realm).perform()
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
index 89657ad882..83f3e87d05 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt
@@ -47,6 +47,7 @@ internal object HomeServerCapabilitiesMapper {
canLoginWithQrCode = entity.canLoginWithQrCode,
canUseThreadReadReceiptsAndNotifications = entity.canUseThreadReadReceiptsAndNotifications,
canRemotelyTogglePushNotificationsOfDevices = entity.canRemotelyTogglePushNotificationsOfDevices,
+ canRedactEventWithRelations = entity.canRedactEventWithRelations,
)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo049.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo049.kt
new file mode 100644
index 0000000000..31a5305777
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo049.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2023 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.internal.database.model.HomeServerCapabilitiesEntityFields
+import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities
+import org.matrix.android.sdk.internal.util.database.RealmMigrator
+
+internal class MigrateSessionTo049(realm: DynamicRealm) : RealmMigrator(realm, 49) {
+
+ override fun doMigrate(realm: DynamicRealm) {
+ realm.schema.get("HomeServerCapabilitiesEntity")
+ ?.addField(HomeServerCapabilitiesEntityFields.CAN_REDACT_EVENT_WITH_RELATIONS, Boolean::class.java)
+ ?.transform { obj ->
+ obj.set(HomeServerCapabilitiesEntityFields.CAN_REDACT_EVENT_WITH_RELATIONS, false)
+ }
+ ?.forceRefreshOfHomeServerCapabilities()
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
index 2b60f7723c..9acdcde7e5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt
@@ -34,6 +34,7 @@ internal open class HomeServerCapabilitiesEntity(
var canLoginWithQrCode: Boolean = false,
var canUseThreadReadReceiptsAndNotifications: Boolean = false,
var canRemotelyTogglePushNotificationsOfDevices: Boolean = false,
+ var canRedactEventWithRelations: Boolean = false,
) : RealmObject() {
companion object
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
index 11e86a5c51..5a6107821d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt
@@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.internal.auth.version.Versions
import org.matrix.android.sdk.internal.auth.version.doesServerSupportLogoutDevices
import org.matrix.android.sdk.internal.auth.version.doesServerSupportQrCodeLogin
+import org.matrix.android.sdk.internal.auth.version.doesServerSupportRedactEventWithRelations
import org.matrix.android.sdk.internal.auth.version.doesServerSupportRemoteToggleOfPushNotifications
import org.matrix.android.sdk.internal.auth.version.doesServerSupportThreadUnreadNotifications
import org.matrix.android.sdk.internal.auth.version.doesServerSupportThreads
@@ -154,6 +155,8 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
getVersionResult.doesServerSupportQrCodeLogin()
homeServerCapabilitiesEntity.canRemotelyTogglePushNotificationsOfDevices =
getVersionResult.doesServerSupportRemoteToggleOfPushNotifications()
+ homeServerCapabilitiesEntity.canRedactEventWithRelations =
+ getVersionResult.doesServerSupportRedactEventWithRelations()
}
if (getWellknownResult != null && getWellknownResult is WellknownResult.Prompt) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
index 34b6ee525d..aa4bdb1dd4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt
@@ -37,6 +37,7 @@ import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse
import org.matrix.android.sdk.internal.session.room.relation.threads.ThreadSummariesResponse
import org.matrix.android.sdk.internal.session.room.reporting.ReportContentBody
import org.matrix.android.sdk.internal.session.room.send.SendResponse
+import org.matrix.android.sdk.internal.session.room.send.model.EventRedactBody
import org.matrix.android.sdk.internal.session.room.tags.TagBody
import org.matrix.android.sdk.internal.session.room.timeline.EventContextResponse
import org.matrix.android.sdk.internal.session.room.timeline.PaginationResponse
@@ -61,7 +62,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "publicRooms")
suspend fun publicRooms(
@Query("server") server: String?,
- @Body publicRoomsParams: PublicRoomsParams
+ @Body publicRoomsParams: PublicRoomsParams,
): PublicRoomsResponse
/**
@@ -91,7 +92,7 @@ internal interface RoomAPI {
@Query("from") from: String,
@Query("dir") dir: String,
@Query("limit") limit: Int?,
- @Query("filter") filter: String?
+ @Query("filter") filter: String?,
): PaginationResponse
/**
@@ -107,7 +108,7 @@ internal interface RoomAPI {
@Path("roomId") roomId: String,
@Query("at") syncToken: String?,
@Query("membership") membership: Membership?,
- @Query("not_membership") notMembership: Membership?
+ @Query("not_membership") notMembership: Membership?,
): RoomMembersResponse
/**
@@ -123,7 +124,7 @@ internal interface RoomAPI {
@Path("txId") txId: String,
@Path("roomId") roomId: String,
@Path("eventType") eventType: String,
- @Body content: Content?
+ @Body content: Content?,
): SendResponse
/**
@@ -139,7 +140,7 @@ internal interface RoomAPI {
@Path("roomId") roomId: String,
@Path("eventId") eventId: String,
@Query("limit") limit: Int,
- @Query("filter") filter: String? = null
+ @Query("filter") filter: String? = null,
): EventContextResponse
/**
@@ -151,7 +152,7 @@ internal interface RoomAPI {
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/event/{eventId}")
suspend fun getEvent(
@Path("roomId") roomId: String,
- @Path("eventId") eventId: String
+ @Path("eventId") eventId: String,
): Event
/**
@@ -163,7 +164,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/read_markers")
suspend fun sendReadMarker(
@Path("roomId") roomId: String,
- @Body markers: Map
+ @Body markers: Map,
)
/**
@@ -174,7 +175,7 @@ internal interface RoomAPI {
@Path("roomId") roomId: String,
@Path("receiptType") receiptType: String,
@Path("eventId") eventId: String,
- @Body body: ReadBody
+ @Body body: ReadBody,
)
/**
@@ -187,7 +188,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/invite")
suspend fun invite(
@Path("roomId") roomId: String,
- @Body body: InviteBody
+ @Body body: InviteBody,
)
/**
@@ -199,7 +200,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/invite")
suspend fun invite3pid(
@Path("roomId") roomId: String,
- @Body body: ThreePidInviteBody
+ @Body body: ThreePidInviteBody,
)
/**
@@ -213,7 +214,7 @@ internal interface RoomAPI {
suspend fun sendStateEvent(
@Path("roomId") roomId: String,
@Path("state_event_type") stateEventType: String,
- @Body params: JsonDict
+ @Body params: JsonDict,
): SendResponse
/**
@@ -229,7 +230,7 @@ internal interface RoomAPI {
@Path("roomId") roomId: String,
@Path("state_event_type") stateEventType: String,
@Path("state_key") stateKey: String,
- @Body params: JsonDict
+ @Body params: JsonDict,
): SendResponse
/**
@@ -257,7 +258,7 @@ internal interface RoomAPI {
@Path("eventType") eventType: String,
@Query("from") from: String? = null,
@Query("to") to: String? = null,
- @Query("limit") limit: Int? = null
+ @Query("limit") limit: Int? = null,
): RelationsResponse
/**
@@ -277,7 +278,7 @@ internal interface RoomAPI {
@Path("relationType") relationType: String,
@Query("from") from: String? = null,
@Query("to") to: String? = null,
- @Query("limit") limit: Int? = null
+ @Query("limit") limit: Int? = null,
): RelationsResponse
/**
@@ -291,7 +292,7 @@ internal interface RoomAPI {
suspend fun join(
@Path("roomIdOrAlias") roomIdOrAlias: String,
@Query("server_name") viaServers: List,
- @Body params: JsonDict
+ @Body params: JsonDict,
): JoinRoomResponse
/**
@@ -303,7 +304,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave")
suspend fun leave(
@Path("roomId") roomId: String,
- @Body params: Map
+ @Body params: Map,
)
/**
@@ -315,7 +316,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/ban")
suspend fun ban(
@Path("roomId") roomId: String,
- @Body userIdAndReason: UserIdAndReason
+ @Body userIdAndReason: UserIdAndReason,
)
/**
@@ -327,7 +328,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/unban")
suspend fun unban(
@Path("roomId") roomId: String,
- @Body userIdAndReason: UserIdAndReason
+ @Body userIdAndReason: UserIdAndReason,
)
/**
@@ -339,7 +340,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/kick")
suspend fun kick(
@Path("roomId") roomId: String,
- @Body userIdAndReason: UserIdAndReason
+ @Body userIdAndReason: UserIdAndReason,
)
/**
@@ -350,14 +351,14 @@ internal interface RoomAPI {
* @param txId the transaction Id
* @param roomId the room id
* @param eventId the event to delete
- * @param reason json containing reason key {"reason": "Indecent material"}
+ * @param body body containing reason key {"reason": "Indecent material"} and with_relations
*/
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/redact/{eventId}/{txnId}")
suspend fun redactEvent(
@Path("txnId") txId: String,
@Path("roomId") roomId: String,
@Path("eventId") eventId: String,
- @Body reason: Map
+ @Body body: EventRedactBody,
): SendResponse
/**
@@ -371,7 +372,7 @@ internal interface RoomAPI {
suspend fun reportContent(
@Path("roomId") roomId: String,
@Path("eventId") eventId: String,
- @Body body: ReportContentBody
+ @Body body: ReportContentBody,
)
/**
@@ -388,7 +389,7 @@ internal interface RoomAPI {
suspend fun sendTypingState(
@Path("roomId") roomId: String,
@Path("userId") userId: String,
- @Body body: TypingBody
+ @Body body: TypingBody,
)
/*
@@ -403,7 +404,7 @@ internal interface RoomAPI {
@Path("userId") userId: String,
@Path("roomId") roomId: String,
@Path("tag") tag: String,
- @Body body: TagBody
+ @Body body: TagBody,
)
/**
@@ -413,7 +414,7 @@ internal interface RoomAPI {
suspend fun deleteTag(
@Path("userId") userId: String,
@Path("roomId") roomId: String,
- @Path("tag") tag: String
+ @Path("tag") tag: String,
)
/**
@@ -424,7 +425,7 @@ internal interface RoomAPI {
@Path("userId") userId: String,
@Path("roomId") roomId: String,
@Path("type") type: String,
- @Body content: JsonDict
+ @Body content: JsonDict,
)
/**
@@ -437,7 +438,7 @@ internal interface RoomAPI {
suspend fun deleteRoomAccountData(
@Path("userId") userId: String,
@Path("roomId") roomId: String,
- @Path("type") type: String
+ @Path("type") type: String,
)
/**
@@ -450,7 +451,7 @@ internal interface RoomAPI {
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/upgrade")
suspend fun upgradeRoom(
@Path("roomId") roomId: String,
- @Body body: RoomUpgradeBody
+ @Body body: RoomUpgradeBody,
): RoomUpgradeResponse
/**
@@ -462,7 +463,7 @@ internal interface RoomAPI {
@GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "im.nheko.summary/rooms/{roomIdOrAlias}/summary")
suspend fun getRoomSummary(
@Path("roomIdOrAlias") roomidOrAlias: String,
- @Query("via") viaServers: List?
+ @Query("via") viaServers: List?,
): RoomStrippedState
@GET(NetworkConstants.URI_API_PREFIX_PATH_V1 + "rooms/{roomId}/threads")
@@ -470,6 +471,6 @@ internal interface RoomAPI {
@Path("roomId") roomId: String,
@Query("include") include: String? = "all",
@Query("from") from: String? = null,
- @Query("limit") limit: Int? = null
+ @Query("limit") limit: Int? = null,
): ThreadSummariesResponse
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
index 9cdbc7ff46..d29e7d8f36 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt
@@ -140,11 +140,11 @@ internal class DefaultSendService @AssistedInject constructor(
.let { sendEvent(it) }
}
- override fun redactEvent(event: Event, reason: String?, additionalContent: Content?): Cancelable {
+ override fun redactEvent(event: Event, reason: String?, withRelations: List?, additionalContent: Content?): Cancelable {
// TODO manage media/attachements?
- val redactionEcho = localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason, additionalContent)
+ val redactionEcho = localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason, withRelations, additionalContent)
.also { createLocalEcho(it) }
- return eventSenderProcessor.postRedaction(redactionEcho, reason)
+ return eventSenderProcessor.postRedaction(redactionEcho, reason, withRelations)
}
override fun resendTextMessage(localEcho: TimelineEvent): Cancelable {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
index d974c597ac..38024b7aa8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt
@@ -70,6 +70,7 @@ import org.matrix.android.sdk.api.util.TextContent
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor
import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory
+import org.matrix.android.sdk.internal.session.room.send.model.EventRedactBody
import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
import org.matrix.android.sdk.internal.util.time.Clock
import java.util.UUID
@@ -795,8 +796,16 @@ internal class LocalEchoEventFactory @Inject constructor(
}
}
*/
- fun createRedactEvent(roomId: String, eventId: String, reason: String?, additionalContent: Content? = null): Event {
+ fun createRedactEvent(roomId: String, eventId: String, reason: String?, withRelations: List? = null, additionalContent: Content? = null): Event {
val localId = LocalEcho.createLocalEchoId()
+ val content = if (reason != null || withRelations != null) {
+ EventRedactBody(
+ reason = reason,
+ withRelations = withRelations,
+ ).toContent().plus(additionalContent.orEmpty())
+ } else {
+ additionalContent
+ }
return Event(
roomId = roomId,
originServerTs = dummyOriginServerTs(),
@@ -804,7 +813,7 @@ internal class LocalEchoEventFactory @Inject constructor(
eventId = localId,
type = EventType.REDACTION,
redacts = eventId,
- content = reason?.let { mapOf("reason" to it).toContent().plus(additionalContent.orEmpty()) } ?: additionalContent,
+ content = content,
unsignedData = UnsignedData(age = null, transactionId = localId)
)
}
@@ -830,10 +839,10 @@ internal class LocalEchoEventFactory @Inject constructor(
createMessageEvent(
roomId,
textContent.toThreadTextContent(
- rootThreadEventId = rootThreadEventId,
- latestThreadEventId = localEchoRepository.getLatestThreadEvent(rootThreadEventId),
- msgType = MessageType.MSGTYPE_TEXT
- ),
+ rootThreadEventId = rootThreadEventId,
+ latestThreadEventId = localEchoRepository.getLatestThreadEvent(rootThreadEventId),
+ msgType = MessageType.MSGTYPE_TEXT
+ ),
additionalContent,
)
} else {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt
index 765c282b65..576f31c64c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RedactEventWorker.kt
@@ -20,8 +20,8 @@ import androidx.work.WorkerParameters
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.internal.SessionManager
+import org.matrix.android.sdk.internal.crypto.tasks.RedactEventTask
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
-import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.session.SessionComponent
import org.matrix.android.sdk.internal.session.room.RoomAPI
import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
@@ -43,27 +43,29 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters, ses
val roomId: String,
val eventId: String,
val reason: String?,
+ val withRelations: List? = null,
override val lastFailureMessage: String? = null
) : SessionWorkerParams
@Inject lateinit var roomAPI: RoomAPI
@Inject lateinit var globalErrorReceiver: GlobalErrorReceiver
+ @Inject lateinit var redactEventTask: RedactEventTask
override fun injectWith(injector: SessionComponent) {
injector.inject(this)
}
override suspend fun doSafeWork(params: Params): Result {
- val eventId = params.eventId
return runCatching {
- executeRequest(globalErrorReceiver) {
- roomAPI.redactEvent(
- params.txID,
- params.roomId,
- eventId,
- if (params.reason == null) emptyMap() else mapOf("reason" to params.reason)
- )
- }
+ redactEventTask.execute(
+ RedactEventTask.Params(
+ txID = params.txID,
+ roomId = params.roomId,
+ eventId = params.eventId,
+ reason = params.reason,
+ withRelations = params.withRelations,
+ )
+ )
}.fold(
{
Result.success()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/model/EventRedactBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/model/EventRedactBody.kt
new file mode 100644
index 0000000000..cf2bc0dc4f
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/model/EventRedactBody.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.room.send.model
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class EventRedactBody(
+ @Json(name = "reason")
+ val reason: String? = null,
+
+ @Json(name = "org.matrix.msc3912.with_relations")
+ val withRelations: List? = null,
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
index 050e321b9c..b285e90c9a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt
@@ -26,9 +26,9 @@ internal interface EventSenderProcessor : SessionLifecycleObserver {
fun postEvent(event: Event, encrypt: Boolean): Cancelable
- fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable
+ fun postRedaction(redactionLocalEcho: Event, reason: String?, withRelations: List? = null): Cancelable
- fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable
+ fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?, withRelations: List? = null): Cancelable
fun postTask(task: QueuedTask): Cancelable
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt
index 2c7eea1e54..929fe7b9a6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt
@@ -101,12 +101,18 @@ internal class EventSenderProcessorCoroutine @Inject constructor(
return postTask(task)
}
- override fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable {
- return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason)
+ override fun postRedaction(redactionLocalEcho: Event, reason: String?, withRelations: List?): Cancelable {
+ return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason, withRelations)
}
- override fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable {
- val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason)
+ override fun postRedaction(
+ redactionLocalEchoId: String,
+ eventToRedactId: String,
+ roomId: String,
+ reason: String?,
+ withRelations: List?
+ ): Cancelable {
+ val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason, withRelations)
return postTask(task)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
index 0eedd4bd4d..a900e4ae5d 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueueMemento.kt
@@ -19,9 +19,11 @@ package org.matrix.android.sdk.internal.session.room.send.queue
import android.content.Context
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.CryptoService
+import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
+import org.matrix.android.sdk.internal.session.room.send.model.EventRedactBody
import timber.log.Timber
import javax.inject.Inject
@@ -107,10 +109,18 @@ internal class QueueMemento @Inject constructor(
info.redactionLocalEcho?.let { localEchoRepository.getUpToDateEcho(it) }?.let {
localEchoRepository.updateSendState(it.eventId!!, it.roomId, SendState.UNSENT)
// try to get reason
- val reason = it.content?.get("reason") as? String
+ val body = it.content.toModel()
if (it.redacts != null && it.roomId != null) {
Timber.d("## Send -Reschedule redact $info")
- eventProcessor.postTask(queuedTaskFactory.createRedactTask(it.eventId, it.redacts, it.roomId, reason))
+ eventProcessor.postTask(
+ queuedTaskFactory.createRedactTask(
+ redactionLocalEcho = it.eventId,
+ eventId = it.redacts,
+ roomId = it.roomId,
+ reason = body?.reason,
+ withRelations = body?.withRelations,
+ )
+ )
}
}
// postTask(queuedTaskFactory.createRedactTask(info.eventToRedactId, info.)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTaskFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTaskFactory.kt
index 90bb47c435..46df7e29f3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTaskFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTaskFactory.kt
@@ -43,12 +43,13 @@ internal class QueuedTaskFactory @Inject constructor(
)
}
- fun createRedactTask(redactionLocalEcho: String, eventId: String, roomId: String, reason: String?): QueuedTask {
+ fun createRedactTask(redactionLocalEcho: String, eventId: String, roomId: String, reason: String?, withRelations: List? = null): QueuedTask {
return RedactQueuedTask(
redactionLocalEchoId = redactionLocalEcho,
toRedactEventId = eventId,
roomId = roomId,
reason = reason,
+ withRelations = withRelations,
redactEventTask = redactEventTask,
localEchoRepository = localEchoRepository,
cancelSendTracker = cancelSendTracker
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
index 0e3d88aa79..f484c24aae 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/RedactQueuedTask.kt
@@ -26,13 +26,14 @@ internal class RedactQueuedTask(
val redactionLocalEchoId: String,
private val roomId: String,
private val reason: String?,
+ private val withRelations: List?,
private val redactEventTask: RedactEventTask,
private val localEchoRepository: LocalEchoRepository,
private val cancelSendTracker: CancelSendTracker
) : QueuedTask(queueIdentifier = roomId, taskIdentifier = redactionLocalEchoId) {
override suspend fun doExecute() {
- redactEventTask.execute(RedactEventTask.Params(redactionLocalEchoId, roomId, toRedactEventId, reason))
+ redactEventTask.execute(RedactEventTask.Params(redactionLocalEchoId, roomId, toRedactEventId, reason, withRelations))
}
override fun onTaskFailed() {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
index 75f62009ea..40c8355117 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt
@@ -19,8 +19,9 @@ package org.matrix.android.sdk.internal.session.sync
import com.zhuinden.monarchy.Monarchy
import io.realm.Realm
import org.matrix.android.sdk.api.MatrixConfiguration
-import org.matrix.android.sdk.api.extensions.measureMetric
import org.matrix.android.sdk.api.extensions.measureSpan
+import org.matrix.android.sdk.api.extensions.measureSpannableMetric
+import org.matrix.android.sdk.api.metrics.SpannableMetricPlugin
import org.matrix.android.sdk.api.metrics.SyncDurationMetricPlugin
import org.matrix.android.sdk.api.session.crypto.CryptoService
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
@@ -70,48 +71,49 @@ internal class SyncResponseHandler @Inject constructor(
suspend fun handleResponse(
syncResponse: SyncResponse,
fromToken: String?,
+ afterPause: Boolean,
reporter: ProgressReporter?
) {
val isInitialSync = fromToken == null
val aggregator = SyncResponsePostTreatmentAggregator()
- relevantPlugins.measureMetric {
+ relevantPlugins.filter { it.shouldReport(isInitialSync, afterPause) }.measureSpannableMetric {
startCryptoService(isInitialSync)
// Handle the to device events before the room ones
// to ensure to decrypt them properly
+ handleToDevice(syncResponse)
- relevantPlugins.measureSpan("task", "handle_to_device") {
- handleToDevice(syncResponse)
- }
val syncLocalTimestampMillis = clock.epochMillis()
// pass live state/crypto related event to crypto
- syncResponse.rooms?.invite?.entries?.map { (roomId, roomSync) ->
- roomSync.inviteState
- ?.events
- ?.filter { it.isStateEvent() }
- ?.forEach {
- cryptoService.onStateEvent(roomId, it, aggregator.cryptoStoreAggregator)
- }
- }
+ relevantPlugins.measureSpan("task", "crypto_session_event_handling") {
+ syncResponse.rooms?.invite?.entries?.map { (roomId, roomSync) ->
+ roomSync.inviteState
+ ?.events
+ ?.filter { it.isStateEvent() }
+ ?.forEach {
+ cryptoService.onStateEvent(roomId, it, aggregator.cryptoStoreAggregator)
+ }
+ }
- syncResponse.rooms?.join?.entries?.map { (roomId, roomSync) ->
- roomSync.state
- ?.events
- ?.filter { it.isStateEvent() }
- ?.forEach {
- cryptoService.onStateEvent(roomId, it, aggregator.cryptoStoreAggregator)
- }
+ syncResponse.rooms?.join?.entries?.map { (roomId, roomSync) ->
+ roomSync.state
+ ?.events
+ ?.filter { it.isStateEvent() }
+ ?.forEach {
+ cryptoService.onStateEvent(roomId, it, aggregator.cryptoStoreAggregator)
+ }
- roomSync.timeline?.events?.forEach {
- if (it.isEncrypted() && !isInitialSync) {
- decryptIfNeeded(it, roomId)
+ roomSync.timeline?.events?.forEach {
+ if (it.isEncrypted() && !isInitialSync) {
+ decryptIfNeeded(it, roomId)
+ }
+ it.ageLocalTs = syncLocalTimestampMillis - (it.unsignedData?.age ?: 0)
+ cryptoService.onLiveEvent(roomId, it, isInitialSync, aggregator.cryptoStoreAggregator)
}
- it.ageLocalTs = syncLocalTimestampMillis - (it.unsignedData?.age ?: 0)
- cryptoService.onLiveEvent(roomId, it, isInitialSync, aggregator.cryptoStoreAggregator)
}
}
@@ -160,8 +162,8 @@ internal class SyncResponseHandler @Inject constructor(
return "RoomSyncHandler$roomId"
}
- private suspend fun startCryptoService(isInitialSync: Boolean) {
- relevantPlugins.measureSpan("task", "start_crypto_service") {
+ private suspend fun List.startCryptoService(isInitialSync: Boolean) {
+ measureSpan("task", "start_crypto_service") {
measureTimeMillis {
if (!cryptoService.isStarted()) {
Timber.v("Should start cryptoService")
@@ -174,7 +176,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private suspend fun handleToDevice(syncResponse: SyncResponse) {
+ private suspend fun List.handleToDevice(syncResponse: SyncResponse) {
+ measureSpan("task", "handle_to_device") {
measureTimeMillis {
Timber.v("Handle toDevice")
cryptoService.receiveSyncChanges(
@@ -185,16 +188,17 @@ internal class SyncResponseHandler @Inject constructor(
}.also {
Timber.v("Finish handling toDevice in $it ms")
}
+ }
}
- private suspend fun startMonarchyTransaction(
+ private suspend fun List.startMonarchyTransaction(
syncResponse: SyncResponse,
isInitialSync: Boolean,
reporter: ProgressReporter?,
aggregator: SyncResponsePostTreatmentAggregator
) {
// Start one big transaction
- relevantPlugins.measureSpan("task", "monarchy_transaction") {
+ measureSpan("task", "monarchy_transaction") {
monarchy.awaitTransaction { realm ->
// IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local)
handleRooms(reporter, syncResponse, realm, isInitialSync, aggregator)
@@ -206,14 +210,14 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private fun handleRooms(
+ private fun List.handleRooms(
reporter: ProgressReporter?,
syncResponse: SyncResponse,
realm: Realm,
isInitialSync: Boolean,
aggregator: SyncResponsePostTreatmentAggregator
) {
- relevantPlugins.measureSpan("task", "handle_rooms") {
+ measureSpan("task", "handle_rooms") {
measureTimeMillis {
Timber.v("Handle rooms")
reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.8f) {
@@ -227,8 +231,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private fun handleAccountData(reporter: ProgressReporter?, realm: Realm, syncResponse: SyncResponse) {
- relevantPlugins.measureSpan("task", "handle_account_data") {
+ private fun List.handleAccountData(reporter: ProgressReporter?, realm: Realm, syncResponse: SyncResponse) {
+ measureSpan("task", "handle_account_data") {
measureTimeMillis {
reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) {
Timber.v("Handle accountData")
@@ -240,8 +244,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private fun handlePresence(realm: Realm, syncResponse: SyncResponse) {
- relevantPlugins.measureSpan("task", "handle_presence") {
+ private fun List.handlePresence(realm: Realm, syncResponse: SyncResponse) {
+ measureSpan("task", "handle_presence") {
measureTimeMillis {
Timber.v("Handle Presence")
presenceSyncHandler.handle(realm, syncResponse.presence)
@@ -251,8 +255,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private suspend fun aggregateSyncResponse(aggregator: SyncResponsePostTreatmentAggregator) {
- relevantPlugins.measureSpan("task", "aggregator_management") {
+ private suspend fun List.aggregateSyncResponse(aggregator: SyncResponsePostTreatmentAggregator) {
+ measureSpan("task", "aggregator_management") {
// Everything else we need to do outside the transaction
measureTimeMillis {
aggregatorHandler.handle(aggregator)
@@ -262,8 +266,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private suspend fun postTreatmentSyncResponse(syncResponse: SyncResponse, isInitialSync: Boolean) {
- relevantPlugins.measureSpan("task", "sync_response_post_treatment") {
+ private suspend fun List.postTreatmentSyncResponse(syncResponse: SyncResponse, isInitialSync: Boolean) {
+ measureSpan("task", "sync_response_post_treatment") {
measureTimeMillis {
syncResponse.rooms?.let {
checkPushRules(it, isInitialSync)
@@ -276,8 +280,8 @@ internal class SyncResponseHandler @Inject constructor(
}
}
- private suspend fun markCryptoSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) {
- relevantPlugins.measureSpan("task", "crypto_sync_handler_onSyncCompleted") {
+ private suspend fun List.markCryptoSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) {
+ measureSpan("task", "crypto_sync_handler_onSyncCompleted") {
measureTimeMillis {
cryptoService.onSyncCompleted(syncResponse, cryptoStoreAggregator)
}.also {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
index 8a287fb0b4..86346cabcf 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt
@@ -151,7 +151,7 @@ internal class DefaultSyncTask @Inject constructor(
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
- syncResponseHandler.handleResponse(syncResponse, token, syncRequestStateTracker)
+ syncResponseHandler.handleResponse(syncResponse, null, afterPause = true, syncRequestStateTracker)
}
syncResponseToReturn = syncResponse
}
@@ -184,7 +184,7 @@ internal class DefaultSyncTask @Inject constructor(
toDevice = nbToDevice,
)
)
- syncResponseHandler.handleResponse(syncResponse, token, null)
+ syncResponseHandler.handleResponse(syncResponse, token, afterPause = params.afterPause, null)
syncResponseToReturn = syncResponse
Timber.tag(loggerTag.value).d("Incremental sync done")
syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncDone)
@@ -264,7 +264,7 @@ internal class DefaultSyncTask @Inject constructor(
Timber.tag(loggerTag.value).d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
- syncResponseHandler.handleResponse(syncResponse, null, syncRequestStateTracker)
+ syncResponseHandler.handleResponse(syncResponse, null, afterPause = true, syncRequestStateTracker)
}
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
syncResponse
diff --git a/tools/release/pushPlayStoreMetaData.sh b/tools/release/pushPlayStoreMetaData.sh
index 2d8fd9b36a..cc24786441 100755
--- a/tools/release/pushPlayStoreMetaData.sh
+++ b/tools/release/pushPlayStoreMetaData.sh
@@ -77,6 +77,15 @@ else
removeFullDes_th=1
fi
+if [[ -f "./fastlane/metadata/android/az-AZ/full_description.txt" ]]; then
+ echo "It appears that file ./fastlane/metadata/android/az-AZ/full_description.txt now exists. This can be removed."
+ removeFullDes_az=0
+else
+ echo "Copy default full description to ./fastlane/metadata/android/az-AZ"
+ cp ./fastlane/metadata/android/en-US/full_description.txt ./fastlane/metadata/android/az-AZ
+ removeFullDes_az=1
+fi
+
# Run fastlane
echo "Run fastlane to push to the PlaysStore"
fastlane deployMeta
@@ -107,4 +116,8 @@ if [[ ${removeFullDes_th} -eq 1 ]]; then
rm ./fastlane/metadata/android/th/full_description.txt
fi
+if [[ ${removeFullDes_az} -eq 1 ]]; then
+ rm ./fastlane/metadata/android/az-AZ/full_description.txt
+fi
+
echo "Success!"
diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh
index f9f5303546..cf9671c1dc 100755
--- a/tools/release/releaseScript.sh
+++ b/tools/release/releaseScript.sh
@@ -167,7 +167,7 @@ printf "Building the app...\n"
./gradlew assembleGplayDebug
printf "\n================================================================================\n"
-printf "Uninstalling previous test app if any...\n"
+printf "Uninstalling previous debug app if any...\n"
adb -e uninstall im.vector.app.debug
printf "\n================================================================================\n"
diff --git a/vector-app/build.gradle b/vector-app/build.gradle
index 06dce76873..03f93eb2dd 100644
--- a/vector-app/build.gradle
+++ b/vector-app/build.gradle
@@ -37,7 +37,7 @@ ext.versionMinor = 5
// Note: even values are reserved for regular release, odd values for hotfix release.
// When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release.
-ext.versionPatch = 22
+ext.versionPatch = 24
static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct'
diff --git a/vector/src/main/java/im/vector/app/core/error/ErrorFormatter.kt b/vector/src/main/java/im/vector/app/core/error/ErrorFormatter.kt
index 13f8997452..0966227917 100644
--- a/vector/src/main/java/im/vector/app/core/error/ErrorFormatter.kt
+++ b/vector/src/main/java/im/vector/app/core/error/ErrorFormatter.kt
@@ -160,8 +160,7 @@ class DefaultErrorFormatter @Inject constructor(
RecordingError.BlockedBySomeoneElse -> stringProvider.getString(R.string.error_voice_broadcast_blocked_by_someone_else_message)
RecordingError.NoPermission -> stringProvider.getString(R.string.error_voice_broadcast_permission_denied_message)
RecordingError.UserAlreadyBroadcasting -> stringProvider.getString(R.string.error_voice_broadcast_already_in_progress_message)
- is VoiceBroadcastFailure.ListeningError.UnableToPlay,
- is VoiceBroadcastFailure.ListeningError.DownloadError -> stringProvider.getString(R.string.error_voice_broadcast_unable_to_play)
+ is VoiceBroadcastFailure.ListeningError -> stringProvider.getString(R.string.error_voice_broadcast_unable_to_play)
}
}
diff --git a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt
index 16e8405887..49dd74d16f 100644
--- a/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt
+++ b/vector/src/main/java/im/vector/app/core/extensions/TimelineEvent.kt
@@ -20,6 +20,7 @@ import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
+import im.vector.app.features.voicebroadcast.model.isVoiceBroadcast
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
@@ -49,3 +50,7 @@ fun TimelineEvent.getVectorLastMessageContent(): MessageContent? {
else -> getLastMessageContent()
}
}
+
+fun TimelineEvent.isVoiceBroadcast(): Boolean {
+ return root.isVoiceBroadcast()
+}
diff --git a/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt b/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
index d69ed01526..04f4d38769 100644
--- a/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
+++ b/vector/src/main/java/im/vector/app/features/analytics/metrics/sentry/SentrySyncDurationMetrics.kt
@@ -34,6 +34,11 @@ class SentrySyncDurationMetrics @Inject constructor() : SyncDurationMetricPlugin
// Stacks to keep spans in LIFO order.
private var spans: Stack = Stack()
+ override fun shouldReport(isInitialSync: Boolean, isAfterPause: Boolean): Boolean {
+ // Report only for initial sync and for sync after pause
+ return isInitialSync || isAfterPause
+ }
+
/**
* Starts the span for a sub-task.
*
@@ -69,6 +74,7 @@ class SentrySyncDurationMetrics @Inject constructor() : SyncDurationMetricPlugin
override fun finishTransaction() {
transaction?.finish()
+ transaction = null
logTransaction("Sentry transaction finished")
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
index c2755e58a3..f4872dbea6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
@@ -32,6 +32,7 @@ import im.vector.app.R
import im.vector.app.SpaceStateHandler
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
+import im.vector.app.core.extensions.isVoiceBroadcast
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.BuildMeta
@@ -860,12 +861,18 @@ class TimelineViewModel @AssistedInject constructor(
private fun handleRedactEvent(action: RoomDetailAction.RedactAction) {
val event = room?.getTimelineEvent(action.targetEventId) ?: return
- if (event.isLiveLocation()) {
- viewModelScope.launch {
- redactLiveLocationShareEventUseCase.execute(event.root, room, action.reason)
+ when {
+ event.isLiveLocation() -> {
+ viewModelScope.launch {
+ redactLiveLocationShareEventUseCase.execute(event.root, room, action.reason)
+ }
+ }
+ event.isVoiceBroadcast() -> {
+ room.sendService().redactEvent(event.root, action.reason, listOf(RelationType.REFERENCE))
+ }
+ else -> {
+ room.sendService().redactEvent(event.root, action.reason)
}
- } else {
- room.sendService().redactEvent(event.root, action.reason)
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastRecordingItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastRecordingItem.kt
index 39d2d73c68..abf14c0867 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastRecordingItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastRecordingItem.kt
@@ -17,6 +17,8 @@
package im.vector.app.features.home.room.detail.timeline.item
import android.widget.ImageButton
+import android.widget.TextView
+import androidx.constraintlayout.widget.Group
import androidx.core.view.isVisible
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
@@ -55,11 +57,11 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
}
override fun renderLiveIndicator(holder: Holder) {
- when (voiceBroadcastState) {
- VoiceBroadcastState.STARTED,
- VoiceBroadcastState.RESUMED -> renderPlayingLiveIndicator(holder)
- VoiceBroadcastState.PAUSED -> renderPausedLiveIndicator(holder)
- VoiceBroadcastState.STOPPED, null -> renderNoLiveIndicator(holder)
+ when (recorder?.recordingState) {
+ VoiceBroadcastRecorder.State.Recording -> renderPlayingLiveIndicator(holder)
+ VoiceBroadcastRecorder.State.Error,
+ VoiceBroadcastRecorder.State.Paused -> renderPausedLiveIndicator(holder)
+ VoiceBroadcastRecorder.State.Idle, null -> renderNoLiveIndicator(holder)
}
}
@@ -85,7 +87,9 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
VoiceBroadcastRecorder.State.Recording -> renderRecordingState(holder)
VoiceBroadcastRecorder.State.Paused -> renderPausedState(holder)
VoiceBroadcastRecorder.State.Idle -> renderStoppedState(holder)
+ VoiceBroadcastRecorder.State.Error -> renderErrorState(holder, true)
}
+ renderLiveIndicator(holder)
}
private fun renderVoiceBroadcastState(holder: Holder) {
@@ -101,6 +105,7 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
private fun renderRecordingState(holder: Holder) = with(holder) {
stopRecordButton.isEnabled = true
recordButton.isEnabled = true
+ renderErrorState(holder, false)
val drawableColor = colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
val drawable = drawableProvider.getDrawable(R.drawable.ic_play_pause_pause, drawableColor)
@@ -113,6 +118,7 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
private fun renderPausedState(holder: Holder) = with(holder) {
stopRecordButton.isEnabled = true
recordButton.isEnabled = true
+ renderErrorState(holder, false)
recordButton.setImageResource(R.drawable.ic_recording_dot)
recordButton.contentDescription = holder.view.resources.getString(R.string.a11y_resume_voice_broadcast_record)
@@ -123,6 +129,12 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
private fun renderStoppedState(holder: Holder) = with(holder) {
recordButton.isEnabled = false
stopRecordButton.isEnabled = false
+ renderErrorState(holder, false)
+ }
+
+ private fun renderErrorState(holder: Holder, isOnError: Boolean) = with(holder) {
+ controlsGroup.isVisible = !isOnError
+ errorView.isVisible = isOnError
}
override fun unbind(holder: Holder) {
@@ -142,6 +154,8 @@ abstract class MessageVoiceBroadcastRecordingItem : AbsMessageVoiceBroadcastItem
val remainingTimeMetadata by bind(R.id.remainingTimeMetadata)
val recordButton by bind(R.id.recordButton)
val stopRecordButton by bind(R.id.stopRecordButton)
+ val errorView by bind(R.id.errorView)
+ val controlsGroup by bind(R.id.controlsGroup)
}
companion object {
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/VoiceBroadcastFailure.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/VoiceBroadcastFailure.kt
index 75863dc042..1f9529a966 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/VoiceBroadcastFailure.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/VoiceBroadcastFailure.kt
@@ -31,6 +31,6 @@ sealed class VoiceBroadcastFailure : Throwable() {
* @property extra an extra code, specific to the error, see [MediaPlayer.OnErrorListener.onError].
*/
data class UnableToPlay(val what: Int, val extra: Int) : ListeningError()
- data class DownloadError(override val cause: Throwable?) : ListeningError()
+ data class PrepareMediaPlayerError(override val cause: Throwable? = null) : ListeningError()
}
}
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt
index 2e1600e4e2..2559f1a7d6 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt
@@ -18,7 +18,6 @@ package im.vector.app.features.voicebroadcast.listening
import android.media.AudioAttributes
import android.media.MediaPlayer
-import android.media.MediaPlayer.OnPreparedListener
import androidx.annotation.MainThread
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.onFirst
@@ -33,10 +32,13 @@ import im.vector.app.features.voicebroadcast.model.VoiceBroadcast
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastEvent
import im.vector.app.features.voicebroadcast.usecase.GetVoiceBroadcastStateEventLiveUseCase
import im.vector.lib.core.utils.timer.CountUpTimer
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
import timber.log.Timber
@@ -63,8 +65,29 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private var voiceBroadcastStateObserver: Job? = null
private var currentMediaPlayer: MediaPlayer? = null
+ private set(value) {
+ Timber.d("## Voice Broadcast | currentMediaPlayer changed: old=${field.hashCode()}, new=${value.hashCode()}")
+ field = value
+ }
private var nextMediaPlayer: MediaPlayer? = null
- private var isPreparingNextPlayer: Boolean = false
+ private set(value) {
+ Timber.d("## Voice Broadcast | nextMediaPlayer changed: old=${field.hashCode()}, new=${value.hashCode()}")
+ field = value
+ }
+
+ private var prepareCurrentPlayerJob: Job? = null
+ set(value) {
+ if (field?.isActive.orFalse()) field?.cancel()
+ field = value
+ }
+ private var prepareNextPlayerJob: Job? = null
+ set(value) {
+ if (field?.isActive.orFalse()) field?.cancel()
+ field = value
+ }
+
+ private val isPreparingCurrentPlayer: Boolean get() = prepareCurrentPlayerJob?.isActive.orFalse()
+ private val isPreparingNextPlayer: Boolean get() = prepareNextPlayerJob?.isActive.orFalse()
private var mostRecentVoiceBroadcastEvent: VoiceBroadcastEvent? = null
@@ -83,7 +106,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
@MainThread
set(value) {
if (field != value) {
- Timber.d("## Voice Broadcast | playingState: $field -> $value")
+ Timber.d("## Voice Broadcast | playingState: ${field::class.java.simpleName} -> ${value::class.java.simpleName}")
field = value
onPlayingStateChanged(value)
}
@@ -174,23 +197,25 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
}
private fun onPlaylistUpdated() {
+ if (isPreparingCurrentPlayer || isPreparingNextPlayer) return
when (playingState) {
State.Playing,
State.Paused -> {
- if (nextMediaPlayer == null && !isPreparingNextPlayer) {
+ if (nextMediaPlayer == null) {
prepareNextMediaPlayer()
}
}
State.Buffering -> {
- val nextItem = if (isLiveListening && playlist.currentSequence == null) {
- // live listening, jump to the last item if playback has not started
- playlist.lastOrNull()
- } else {
- // not live or playback already started, request next item
- playlist.getNextItem()
- }
- if (nextItem != null) {
- startPlayback(nextItem.startTime)
+ val savedPosition = currentVoiceBroadcast?.voiceBroadcastId?.let { playbackTracker.getPlaybackTime(it) }
+ when {
+ // resume playback from the next sequence item
+ playlist.currentSequence != null -> playlist.getNextItem()?.let { startPlayback(it.startTime) }
+ // resume playback from the saved position, if any
+ savedPosition != null -> startPlayback(savedPosition)
+ // live listening, jump to the last item
+ isLiveListening -> playlist.lastOrNull()?.let { startPlayback(it.startTime) }
+ // start playback from the beginning
+ else -> startPlayback(0)
}
}
is State.Error -> Unit
@@ -205,19 +230,16 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
val content = playlistItem?.audioEvent?.content ?: run { Timber.w("## Voice Broadcast | No content to play at position $position"); return }
val sequence = playlistItem.sequence ?: run { Timber.w("## Voice Broadcast | Playlist item has no sequence"); return }
val sequencePosition = position - playlistItem.startTime
- sessionScope.launch {
+ prepareCurrentPlayerJob = sessionScope.launch {
try {
- prepareMediaPlayer(content) { mp ->
- currentMediaPlayer = mp
- playlist.currentSequence = sequence
- mp.start()
- if (sequencePosition > 0) {
- mp.seekTo(sequencePosition)
- }
- playingState = State.Playing
- prepareNextMediaPlayer()
+ val mp = prepareMediaPlayer(content)
+ playlist.currentSequence = sequence - 1 // will be incremented in onNextMediaPlayerStarted
+ mp.start()
+ if (sequencePosition > 0) {
+ mp.seekTo(sequencePosition)
}
- } catch (failure: VoiceBroadcastFailure.ListeningError.DownloadError) {
+ onNextMediaPlayerStarted(mp)
+ } catch (failure: VoiceBroadcastFailure.ListeningError) {
playingState = State.Error(failure)
}
}
@@ -248,7 +270,6 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
playbackTracker.updatePausedAtPlaybackTime(voiceBroadcast.voiceBroadcastId, positionMillis, positionMillis.toFloat() / duration)
}
playingState == State.Playing || playingState == State.Buffering -> {
- updateLiveListeningMode(positionMillis)
startPlayback(positionMillis)
}
playingState == State.Idle || playingState == State.Paused -> {
@@ -260,28 +281,24 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
private fun prepareNextMediaPlayer() {
val nextItem = playlist.getNextItem()
- if (nextItem != null) {
- isPreparingNextPlayer = true
- sessionScope.launch {
+ if (!isPreparingNextPlayer && nextMediaPlayer == null && nextItem != null) {
+ prepareNextPlayerJob = sessionScope.launch {
try {
- prepareMediaPlayer(nextItem.audioEvent.content) { mp ->
- isPreparingNextPlayer = false
- nextMediaPlayer = mp
- when (playingState) {
- State.Playing,
- State.Paused -> {
- currentMediaPlayer?.setNextMediaPlayer(mp)
- }
- State.Buffering -> {
- mp.start()
- onNextMediaPlayerStarted(mp)
- }
- is State.Error,
- State.Idle -> stopPlayer()
+ val mp = prepareMediaPlayer(nextItem.audioEvent.content)
+ nextMediaPlayer = mp
+ when (playingState) {
+ State.Playing,
+ State.Paused -> {
+ currentMediaPlayer?.setNextMediaPlayer(mp)
}
+ State.Buffering -> {
+ mp.start()
+ onNextMediaPlayerStarted(mp)
+ }
+ is State.Error,
+ State.Idle -> stopPlayer()
}
- } catch (failure: VoiceBroadcastFailure.ListeningError.DownloadError) {
- isPreparingNextPlayer = false
+ } catch (failure: VoiceBroadcastFailure.ListeningError) {
// Do not change the playingState if the current player is still valid,
// the error will be thrown again when switching to the next player
if (playingState == State.Buffering || tryOrNull { currentMediaPlayer?.isPlaying } != true) {
@@ -292,18 +309,30 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
}
}
- private suspend fun prepareMediaPlayer(messageAudioContent: MessageAudioContent, onPreparedListener: OnPreparedListener): MediaPlayer {
+ /**
+ * Create and prepare a [MediaPlayer] instance for the given [messageAudioContent].
+ * This methods takes care of downloading the audio file and returns the player when it is ready to use.
+ *
+ * Do not forget to release the resulting player when you don't need it anymore, in case you cancel the job related to this method, the player will be
+ * automatically released.
+ */
+ private suspend fun prepareMediaPlayer(messageAudioContent: MessageAudioContent): MediaPlayer {
// Download can fail
val audioFile = try {
session.fileService().downloadFile(messageAudioContent)
} catch (failure: Throwable) {
Timber.e(failure, "Voice Broadcast | Download has failed: $failure")
- throw VoiceBroadcastFailure.ListeningError.DownloadError(failure)
+ throw VoiceBroadcastFailure.ListeningError.PrepareMediaPlayerError(failure)
}
- return audioFile.inputStream().use { fis ->
- MediaPlayer().apply {
- setOnErrorListener(mediaPlayerListener)
+ val latch = CompletableDeferred()
+ val mp = MediaPlayer()
+ return try {
+ mp.apply {
+ setOnErrorListener { mp, what, extra ->
+ mediaPlayerListener.onError(mp, what, extra)
+ latch.completeExceptionally(VoiceBroadcastFailure.ListeningError.PrepareMediaPlayerError())
+ }
setAudioAttributes(
AudioAttributes.Builder()
// Do not use CONTENT_TYPE_SPEECH / USAGE_VOICE_COMMUNICATION because we want to play loud here
@@ -311,12 +340,16 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
)
- setDataSource(fis.fd)
+ audioFile.inputStream().use { fis -> setDataSource(fis.fd) }
setOnInfoListener(mediaPlayerListener)
- setOnPreparedListener(onPreparedListener)
+ setOnPreparedListener(latch::complete)
setOnCompletionListener(mediaPlayerListener)
prepareAsync()
}
+ latch.await()
+ } catch (e: CancellationException) {
+ mp.release()
+ throw e
}
}
@@ -327,7 +360,9 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
nextMediaPlayer?.release()
nextMediaPlayer = null
- isPreparingNextPlayer = false
+
+ prepareCurrentPlayerJob = null
+ prepareNextPlayerJob = null
}
private fun onPlayingStateChanged(playingState: State) {
@@ -357,36 +392,12 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
/**
* Update the live listening state according to:
* - the voice broadcast state (started/paused/resumed/stopped),
- * - the playing state (IDLE, PLAYING, PAUSED, BUFFERING),
- * - the potential seek position (backward/forward).
+ * - the playing state (IDLE, PLAYING, PAUSED, BUFFERING).
*/
- private fun updateLiveListeningMode(seekPosition: Int? = null) {
- isLiveListening = when {
- // the current voice broadcast is not live (ended)
- mostRecentVoiceBroadcastEvent?.isLive != true -> false
- // the player is stopped or paused
- playingState == State.Idle || playingState == State.Paused -> false
- seekPosition != null -> {
- val seekDirection = seekPosition.compareTo(getCurrentPlaybackPosition() ?: 0)
- val newSequence = playlist.findByPosition(seekPosition)?.sequence
- // the user has sought forward
- if (seekDirection >= 0) {
- // stay in live or latest sequence reached
- isLiveListening || newSequence == playlist.lastOrNull()?.sequence
- }
- // the user has sought backward
- else {
- // was in live and stay in the same sequence
- isLiveListening && newSequence == playlist.currentSequence
- }
- }
- // if there is no saved position, go in live
- getCurrentPlaybackPosition() == null -> true
- // if we reached the latest sequence, go in live
- playlist.currentSequence == playlist.lastOrNull()?.sequence -> true
- // otherwise, do not change
- else -> isLiveListening
- }
+ private fun updateLiveListeningMode() {
+ val isLiveVoiceBroadcast = mostRecentVoiceBroadcastEvent?.isLive.orFalse()
+ val isPlaying = playingState == State.Playing || playingState == State.Buffering
+ isLiveListening = isLiveVoiceBroadcast && isPlaying
}
private fun onLiveListeningChanged(isLiveListening: Boolean) {
@@ -439,7 +450,10 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
if (currentMediaPlayer == mp) {
currentMediaPlayer = null
} else {
- error("The media player which has completed mismatches the current media player instance.")
+ Timber.w(
+ "## Voice Broadcast | onCompletion: The media player which has completed mismatches the current media player instance.\n" +
+ "currentMediaPlayer=${currentMediaPlayer.hashCode()}, mp=${mp.hashCode()}"
+ )
}
// Next media player is already attached to this player and will start playing automatically
@@ -458,7 +472,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
}
override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
- Timber.d("## Voice Broadcast | onError: what=$what, extra=$extra")
+ Timber.w("## Voice Broadcast | onError: what=$what, extra=$extra")
// Do not change the playingState if the current player is still valid,
// the error will be thrown again when switching to the next player
if (playingState == State.Buffering || tryOrNull { currentMediaPlayer?.isPlaying } != true) {
@@ -503,7 +517,8 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
}
}
State.Idle -> {
- if (playbackTime == null || percentage == null || (playlist.duration - playbackTime) < 50) {
+ // restart the playback time if player completed with less than 250 ms remaining time
+ if (playbackTime == null || percentage == null || (playlist.duration - playbackTime) < 250) {
playbackTracker.stopPlayback(id)
} else {
playbackTracker.updatePausedAtPlaybackTime(id, playbackTime, percentage)
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/model/VoiceBroadcastEvent.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/model/VoiceBroadcastEvent.kt
index d464a253d3..bcc0b39f8e 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/model/VoiceBroadcastEvent.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/model/VoiceBroadcastEvent.kt
@@ -49,7 +49,9 @@ value class VoiceBroadcastEvent(val root: Event) {
get() = root.content.toModel()
}
+fun Event.isVoiceBroadcast() = type == VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO
+
/**
* Map a [VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO] state event to a [VoiceBroadcastEvent].
*/
-fun Event.asVoiceBroadcastEvent() = if (type == VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO) VoiceBroadcastEvent(this) else null
+fun Event.asVoiceBroadcastEvent() = if (isVoiceBroadcast()) VoiceBroadcastEvent(this) else null
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorder.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorder.kt
index 00e4bb17dd..4f8b614e3a 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorder.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorder.kt
@@ -33,6 +33,8 @@ interface VoiceBroadcastRecorder : VoiceRecorder {
val currentRemainingTime: Long?
fun startRecordVoiceBroadcast(voiceBroadcast: VoiceBroadcast, chunkLength: Int, maxLength: Int)
+
+ fun pauseOnError()
fun addListener(listener: Listener)
fun removeListener(listener: Listener)
@@ -46,5 +48,6 @@ interface VoiceBroadcastRecorder : VoiceRecorder {
Recording,
Paused,
Idle,
+ Error,
}
}
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorderQ.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorderQ.kt
index 2da807293f..7ca6ab3c9c 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorderQ.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/VoiceBroadcastRecorderQ.kt
@@ -29,10 +29,14 @@ import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import im.vector.app.features.voicebroadcast.usecase.GetVoiceBroadcastStateEventLiveUseCase
import im.vector.lib.core.utils.timer.CountUpTimer
import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
+import org.matrix.android.sdk.api.session.sync.SyncState
+import org.matrix.android.sdk.flow.flow
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
@@ -47,6 +51,7 @@ class VoiceBroadcastRecorderQ(
private val sessionScope get() = session.coroutineScope
private var voiceBroadcastStateObserver: Job? = null
+ private var syncStateObserver: Job? = null
private var maxFileSize = 0L // zero or negative for no limit
private var currentVoiceBroadcast: VoiceBroadcast? = null
@@ -96,21 +101,36 @@ class VoiceBroadcastRecorderQ(
observeVoiceBroadcastStateEvent(voiceBroadcast)
}
- override fun pauseRecord() {
+ override fun startRecord(roomId: String) {
+ super.startRecord(roomId)
+ observeConnectionState()
+ }
+
+ override fun pauseOnError() {
if (recordingState != VoiceBroadcastRecorder.State.Recording) return
- tryOrNull { mediaRecorder?.stop() }
- mediaRecorder?.reset()
+
+ pauseRecorder()
+ stopObservingConnectionState()
+ recordingState = VoiceBroadcastRecorder.State.Error
+ }
+
+ override fun pauseRecord() {
+ if (recordingState !in arrayOf(VoiceBroadcastRecorder.State.Recording, VoiceBroadcastRecorder.State.Error)) return
+
+ pauseRecorder()
+ stopObservingConnectionState()
recordingState = VoiceBroadcastRecorder.State.Paused
- recordingTicker.pause()
notifyOutputFileCreated()
}
override fun resumeRecord() {
if (recordingState != VoiceBroadcastRecorder.State.Paused) return
+
currentSequence++
currentVoiceBroadcast?.let { startRecord(it.roomId) }
recordingState = VoiceBroadcastRecorder.State.Recording
recordingTicker.resume()
+ observeConnectionState()
}
override fun stopRecord() {
@@ -128,6 +148,8 @@ class VoiceBroadcastRecorderQ(
voiceBroadcastStateObserver?.cancel()
voiceBroadcastStateObserver = null
+ stopObservingConnectionState()
+
// Reset data
currentSequence = 0
currentMaxLength = 0
@@ -197,6 +219,27 @@ class VoiceBroadcastRecorderQ(
}
}
+ private fun pauseRecorder() {
+ if (recordingState != VoiceBroadcastRecorder.State.Recording) return
+
+ tryOrNull { mediaRecorder?.stop() }
+ mediaRecorder?.reset()
+ recordingTicker.pause()
+ }
+
+ private fun observeConnectionState() {
+ syncStateObserver = session.flow().liveSyncState()
+ .distinctUntilChanged()
+ .filter { it is SyncState.NoNetwork }
+ .onEach { pauseOnError() }
+ .launchIn(sessionScope)
+ }
+
+ private fun stopObservingConnectionState() {
+ syncStateObserver?.cancel()
+ syncStateObserver = null
+ }
+
private inner class RecordingTicker(
private var recordingTicker: CountUpTimer? = null,
) {
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/PauseVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/PauseVoiceBroadcastUseCase.kt
index 0b22d7adf5..ee51f8280b 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/PauseVoiceBroadcastUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/PauseVoiceBroadcastUseCase.kt
@@ -16,17 +16,25 @@
package im.vector.app.features.voicebroadcast.recording.usecase
+import im.vector.app.features.session.coroutineScope
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
import im.vector.app.features.voicebroadcast.recording.VoiceBroadcastRecorder
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.take
+import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
+import org.matrix.android.sdk.api.session.sync.SyncState
+import org.matrix.android.sdk.flow.flow
import timber.log.Timber
import javax.inject.Inject
@@ -51,25 +59,35 @@ class PauseVoiceBroadcastUseCase @Inject constructor(
}
}
- private suspend fun pauseVoiceBroadcast(room: Room, reference: RelationDefaultContent?) {
+ private suspend fun pauseVoiceBroadcast(room: Room, reference: RelationDefaultContent?, remainingRetry: Int = 3) {
Timber.d("## PauseVoiceBroadcastUseCase: Send new voice broadcast info state event")
- // save the last sequence number and immediately pause the recording
- val lastSequence = voiceBroadcastRecorder?.currentSequence
- pauseRecording()
+ try {
+ // save the last sequence number and immediately pause the recording
+ val lastSequence = voiceBroadcastRecorder?.currentSequence
- room.stateService().sendStateEvent(
- eventType = VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
- stateKey = session.myUserId,
- body = MessageVoiceBroadcastInfoContent(
- relatesTo = reference,
- voiceBroadcastStateStr = VoiceBroadcastState.PAUSED.value,
- lastChunkSequence = lastSequence,
- ).toContent(),
- )
- }
+ room.stateService().sendStateEvent(
+ eventType = VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
+ stateKey = session.myUserId,
+ body = MessageVoiceBroadcastInfoContent(
+ relatesTo = reference,
+ voiceBroadcastStateStr = VoiceBroadcastState.PAUSED.value,
+ lastChunkSequence = lastSequence,
+ ).toContent(),
+ )
- private fun pauseRecording() {
- voiceBroadcastRecorder?.pauseRecord()
+ voiceBroadcastRecorder?.pauseRecord()
+ } catch (e: Failure) {
+ if (remainingRetry > 0) {
+ voiceBroadcastRecorder?.pauseOnError()
+ // Retry if there is no network issue (sync is running well)
+ session.flow().liveSyncState()
+ .filter { it is SyncState.Running }
+ .take(1)
+ .onEach { pauseVoiceBroadcast(room, reference, remainingRetry - 1) }
+ .launchIn(session.coroutineScope)
+ }
+ throw e
+ }
}
}
diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
index 87ea49cece..d807c67f74 100644
--- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt
@@ -58,6 +58,7 @@ class StartVoiceBroadcastUseCase @Inject constructor(
private val buildMeta: BuildMeta,
private val getRoomLiveVoiceBroadcastsUseCase: GetRoomLiveVoiceBroadcastsUseCase,
private val stopVoiceBroadcastUseCase: StopVoiceBroadcastUseCase,
+ private val pauseVoiceBroadcastUseCase: PauseVoiceBroadcastUseCase,
) {
suspend fun execute(roomId: String): Result = runCatching {
@@ -103,6 +104,14 @@ class StartVoiceBroadcastUseCase @Inject constructor(
session.coroutineScope.launch { stopVoiceBroadcastUseCase.execute(room.roomId) }
}
}
+
+ override fun onStateUpdated(state: VoiceBroadcastRecorder.State) {
+ if (state == VoiceBroadcastRecorder.State.Error) {
+ session.coroutineScope.launch {
+ pauseVoiceBroadcastUseCase.execute(room.roomId)
+ }
+ }
+ }
})
voiceBroadcastRecorder?.startRecordVoiceBroadcast(voiceBroadcast, chunkLength, maxLength)
}
diff --git a/vector/src/main/res/layout/item_timeline_event_voice_broadcast_listening_stub.xml b/vector/src/main/res/layout/item_timeline_event_voice_broadcast_listening_stub.xml
index 98a9ccaa2d..de9b92884c 100644
--- a/vector/src/main/res/layout/item_timeline_event_voice_broadcast_listening_stub.xml
+++ b/vector/src/main/res/layout/item_timeline_event_voice_broadcast_listening_stub.xml
@@ -40,51 +40,59 @@
-
+ app:layout_constraintTop_toBottomOf="@id/titleText">
-
+
-
+
-
+
-
+
+
+ app:constraint_referenced_ids="roomAvatarImageView,titleText,metadataGroup" />
+ tools:text="@sample/rooms.json/data/name" />
-
+ app:layout_constraintTop_toBottomOf="@id/titleText">
-
+
-
+
+
+ app:constraint_referenced_ids="roomAvatarImageView,titleText,metadataGroup" />
+
+
+
+
diff --git a/vector/src/main/res/layout/view_voice_broadcast_buffering.xml b/vector/src/main/res/layout/view_voice_broadcast_buffering.xml
index e292169537..2d62388288 100644
--- a/vector/src/main/res/layout/view_voice_broadcast_buffering.xml
+++ b/vector/src/main/res/layout/view_voice_broadcast_buffering.xml
@@ -21,5 +21,5 @@
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/a11y_voice_broadcast_buffering" />
+ android:text="@string/voice_broadcast_buffering" />
diff --git a/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt
index 5dfdd379e0..9aa0ddf3b2 100644
--- a/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt
@@ -60,7 +60,8 @@ class StartVoiceBroadcastUseCaseTest {
context = FakeContext().instance,
buildMeta = mockk(),
getRoomLiveVoiceBroadcastsUseCase = fakeGetRoomLiveVoiceBroadcastsUseCase,
- stopVoiceBroadcastUseCase = mockk()
+ stopVoiceBroadcastUseCase = mockk(),
+ pauseVoiceBroadcastUseCase = mockk(),
)
)