From 3267a0410a9a0bb69a46e0fca70491e3687413cd Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Thu, 7 Apr 2022 02:18:19 -0700 Subject: [PATCH 001/136] fix: tweak styling of message bubbles * Decreases the size of rounded corners * Increases the maximum width of message bubbles to help avoid unnecessary unused space on screen Signed-off-by: Danny Seymour --- changelog.d/5712.misc | 1 + library/ui-styles/src/main/res/values/dimens.xml | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/5712.misc diff --git a/changelog.d/5712.misc b/changelog.d/5712.misc new file mode 100644 index 0000000000..549306c63f --- /dev/null +++ b/changelog.d/5712.misc @@ -0,0 +1 @@ +Decreases the size of rounded corners and increases the maximum width of message bubbles to help avoid unnecessary unused space on screen diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index 81d5a77297..419390129a 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -49,9 +49,9 @@ 28dp - 62dp - 300dp - 12dp + 6dp + 350sp + 8dp 0.05 From a97addfa3be0871438e15e543b8ebebfb4c47660 Mon Sep 17 00:00:00 2001 From: rudmannn <109571086+rudmannn@users.noreply.github.com> Date: Sun, 7 Aug 2022 11:14:10 +0800 Subject: [PATCH 002/136] replace android:gravity for backward compatibility --- vector/src/main/res/drawable/poll_option_checked.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/drawable/poll_option_checked.xml b/vector/src/main/res/drawable/poll_option_checked.xml index 28ab94a421..2324792eac 100644 --- a/vector/src/main/res/drawable/poll_option_checked.xml +++ b/vector/src/main/res/drawable/poll_option_checked.xml @@ -10,5 +10,9 @@ - \ No newline at end of file + android:top="2dp" + android:bottom="2dp" + android:left="2dp" + android:right="2dp" + /> + From cd71abeb9fe70777808ed15382ca9248ec1eeef7 Mon Sep 17 00:00:00 2001 From: eidonia Date: Sat, 6 Aug 2022 01:32:21 +0200 Subject: [PATCH 003/136] [Bugfix #5029] disable emoji keyboard not applies to reply Signed-off-by: eidonia --- changelog.d/5029.bugfix | 1 + .../app/features/home/room/detail/TimelineFragment.kt | 6 ++++++ .../home/room/detail/composer/MessageComposerView.kt | 3 +++ vector/src/main/res/layout/composer_layout.xml | 4 +++- .../res/layout/composer_layout_constraint_set_compact.xml | 4 +++- .../res/layout/composer_layout_constraint_set_expanded.xml | 4 +++- 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 changelog.d/5029.bugfix diff --git a/changelog.d/5029.bugfix b/changelog.d/5029.bugfix new file mode 100644 index 0000000000..9e8bbd7b7b --- /dev/null +++ b/changelog.d/5029.bugfix @@ -0,0 +1 @@ +Disable emoji keyboard not applies in reply diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index f164183914..f67dca48f6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -353,6 +353,8 @@ class TimelineFragment @Inject constructor( private var lockSendButton = false private val currentCallsViewPresenter = CurrentCallsViewPresenter() + private val isEmojiKeyboardVisible: Boolean + get() = vectorPreferences.showEmojiKeyboard() private val lazyLoadedViews = RoomDetailLazyLoadedViews() private val emojiPopup: EmojiPopup by lifecycleAwareLazy { @@ -1571,6 +1573,10 @@ class TimelineFragment @Inject constructor( attachmentTypeSelector.show(views.composerLayout.views.attachmentButton) } + override fun onExpandOrCompactChange() { + views.composerLayout.views.composerEmojiButton.isVisible = isEmojiKeyboardVisible + } + override fun onSendMessage(text: CharSequence) { sendTextMessage(text) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerView.kt index 1522960cc9..b1b2c87e9c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerView.kt @@ -46,6 +46,7 @@ class MessageComposerView @JvmOverloads constructor( fun onCloseRelatedMessage() fun onSendMessage(text: CharSequence) fun onAddAttachment() + fun onExpandOrCompactChange() } val views: ComposerLayoutBinding @@ -96,6 +97,7 @@ class MessageComposerView @JvmOverloads constructor( } currentConstraintSetId = R.layout.composer_layout_constraint_set_compact applyNewConstraintSet(animate, transitionComplete) + callback?.onExpandOrCompactChange() } fun expand(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) { @@ -105,6 +107,7 @@ class MessageComposerView @JvmOverloads constructor( } currentConstraintSetId = R.layout.composer_layout_constraint_set_expanded applyNewConstraintSet(animate, transitionComplete) + callback?.onExpandOrCompactChange() } fun setTextIfDifferent(text: CharSequence?): Boolean { diff --git a/vector/src/main/res/layout/composer_layout.xml b/vector/src/main/res/layout/composer_layout.xml index bed10f7606..fb0d80278a 100644 --- a/vector/src/main/res/layout/composer_layout.xml +++ b/vector/src/main/res/layout/composer_layout.xml @@ -119,8 +119,10 @@ android:background="?android:attr/selectableItemBackground" android:contentDescription="@string/a11y_open_emoji_picker" android:src="@drawable/ic_insert_emoji" + android:visibility="invisible" app:tint="?vctr_content_tertiary" - tools:ignore="MissingConstraints,MissingPrefix" /> + tools:ignore="MissingConstraints,MissingPrefix" + tools:visibility="visible" /> + tools:ignore="MissingPrefix" + tools:visibility="visible" /> + tools:ignore="MissingPrefix" + tools:visibility="visible" /> Date: Tue, 31 May 2022 21:53:47 +0200 Subject: [PATCH 004/136] Implement Mode.ANIMATED_THUMBNAIL used for autoplaying animated images This patch introduces a new `ImageContentRenderer` mode used for autoplaying animated images. The mode shares url resolving semantics with `FULL_SIZE` and `STICKER`, as such not just fetching thumbnail data but shares sizing semantics with `THUMBNAIL` (scaling by image height). This change fixes animated images not playing in cases in which only a static thumbnail would be loaded. This new mode will only be chosen if the message content is actually a playable image, as such limiting bandwith usage to the required amount by avoiding to load normal images fully (still fetching animated images will increase bandwith usage as a whole of course). Signed-off-by: networkException --- .../room/detail/timeline/factory/MessageItemFactory.kt | 9 ++++++++- .../im/vector/app/features/media/ImageContentRenderer.kt | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 28e256c064..fece5786fe 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -453,12 +453,15 @@ class MessageItemFactory @Inject constructor( maxWidth = maxWidth, allowNonMxcUrls = informationData.sendState.isSending() ) + + val playable = messageContent.mimeType == MimeTypes.Gif + return MessageImageVideoItem_() .attributes(attributes) .leftGuideline(avatarSizeProvider.leftGuideline) .imageContentRenderer(imageContentRenderer) .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder) - .playable(messageContent.mimeType == MimeTypes.Gif) + .playable(playable) .highlighted(highlight) .mediaData(data) .apply { @@ -472,6 +475,10 @@ class MessageItemFactory @Inject constructor( callback?.onImageMessageClicked(messageContent, data, view, emptyList()) } } + }.apply { + if (playable && vectorPreferences.autoplayAnimatedImages()) { + mode(ImageContentRenderer.Mode.ANIMATED_THUMBNAIL) + } } } diff --git a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt index 74c9b5c6b8..65d37b0d0d 100644 --- a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt @@ -85,6 +85,7 @@ class ImageContentRenderer @Inject constructor( enum class Mode { FULL_SIZE, + ANIMATED_THUMBNAIL, THUMBNAIL, STICKER } @@ -231,6 +232,7 @@ class ImageContentRenderer @Inject constructor( val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver() val resolvedUrl = when (mode) { Mode.FULL_SIZE, + Mode.ANIMATED_THUMBNAIL, Mode.STICKER -> resolveUrl(data) Mode.THUMBNAIL -> contentUrlResolver.resolveThumbnail(data.url, size.width, size.height, ContentUrlResolver.ThumbnailMethod.SCALE) } @@ -269,6 +271,7 @@ class ImageContentRenderer @Inject constructor( finalHeight = height finalWidth = width } + Mode.ANIMATED_THUMBNAIL, Mode.THUMBNAIL -> { finalHeight = min(maxImageWidth * height / width, maxImageHeight) finalWidth = finalHeight * width / height From 5fede491ee9d7bc0ce449d15b00ccca8e484bde9 Mon Sep 17 00:00:00 2001 From: networkException Date: Tue, 31 May 2022 22:05:05 +0200 Subject: [PATCH 005/136] ImageContentRenderer: Only animate images using ANIMATED_THUMBNAIL mode This patch removes the dependency on `VectorSettings` as well as only enable animated rendering if the image is actually playable. Signed-off-by: networkException --- .../java/im/vector/app/features/media/ImageContentRenderer.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt index 65d37b0d0d..333b1f0eae 100644 --- a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt @@ -38,7 +38,6 @@ import im.vector.app.core.glide.GlideRequest import im.vector.app.core.glide.GlideRequests import im.vector.app.core.ui.model.Size import im.vector.app.core.utils.DimensionConverter -import im.vector.app.features.settings.VectorPreferences import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.content.ContentUrlResolver @@ -65,7 +64,6 @@ class ImageContentRenderer @Inject constructor( private val localFilesHelper: LocalFilesHelper, private val activeSessionHolder: ActiveSessionHolder, private val dimensionConverter: DimensionConverter, - private val vectorPreferences: VectorPreferences ) { @Parcelize @@ -134,7 +132,7 @@ class ImageContentRenderer @Inject constructor( createGlideRequest(data, mode, imageView, size) .let { - if (vectorPreferences.autoplayAnimatedImages()) it + if (mode == Mode.ANIMATED_THUMBNAIL) it else it.dontAnimate() } .transform(cornerTransformation) From 2bca94d92b57987cc61b9a3a32ad5a6e1028a841 Mon Sep 17 00:00:00 2001 From: networkException Date: Tue, 31 May 2022 22:48:17 +0200 Subject: [PATCH 006/136] Changelog: Add .bugfix entry for pull request #6215 Signed-off-by: networkException --- changelog.d/6215.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6215.bugfix diff --git a/changelog.d/6215.bugfix b/changelog.d/6215.bugfix new file mode 100644 index 0000000000..5291d7d604 --- /dev/null +++ b/changelog.d/6215.bugfix @@ -0,0 +1 @@ +Fix animated images not autoplaying sometimes if only a thumbnail was fetched from the server From 6452a95e0a19d84c3fb898541c033e000be576ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artjom=20K=C3=B6nig?= Date: Mon, 22 Aug 2022 13:36:53 +0200 Subject: [PATCH 007/136] clean up pin code and biometrics on logout --- changelog.d/6906.bugfix | 1 + .../src/main/java/im/vector/app/features/MainActivity.kt | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 changelog.d/6906.bugfix diff --git a/changelog.d/6906.bugfix b/changelog.d/6906.bugfix new file mode 100644 index 0000000000..9b6a76f5cb --- /dev/null +++ b/changelog.d/6906.bugfix @@ -0,0 +1 @@ +Delete pin code key and the key used for biometrics authentication on logout diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 14fae80325..cb77911314 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -41,9 +41,10 @@ import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.ShortcutsHandler import im.vector.app.features.notifications.NotificationDrawerManager -import im.vector.app.features.pin.PinCodeStore import im.vector.app.features.pin.PinLocker import im.vector.app.features.pin.UnlockedActivity +import im.vector.app.features.pin.lockscreen.crypto.LockScreenKeyRepository +import im.vector.app.features.pin.lockscreen.pincode.PinCodeHelper import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.session.VectorSessionStore import im.vector.app.features.settings.VectorPreferences @@ -133,10 +134,11 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity @Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var uiStateRepository: UiStateRepository @Inject lateinit var shortcutsHandler: ShortcutsHandler - @Inject lateinit var pinCodeStore: PinCodeStore + @Inject lateinit var pinCodeHelper: PinCodeHelper @Inject lateinit var pinLocker: PinLocker @Inject lateinit var popupAlertManager: PopupAlertManager @Inject lateinit var vectorAnalytics: VectorAnalytics + @Inject lateinit var lockScreenKeyRepository: LockScreenKeyRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -284,9 +286,10 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity vectorPreferences.clearPreferences() uiStateRepository.reset() pinLocker.unlock() - pinCodeStore.deletePinCode() + pinCodeHelper.deletePinCode() vectorAnalytics.onSignOut() vectorSessionStore.clear() + lockScreenKeyRepository.deleteSystemKey() } withContext(Dispatchers.IO) { // On BG thread From 33e613fe963f06c59abcf5c01e9f95f1ce82fee6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Sep 2022 14:31:31 +0000 Subject: [PATCH 008/136] Bump dagger from 2.42 to 2.44 Bumps `dagger` from 2.42 to 2.44. Updates `hilt-android-gradle-plugin` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) Updates `dagger` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) Updates `dagger-compiler` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) Updates `hilt-android` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) Updates `hilt-android-testing` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) Updates `hilt-compiler` from 2.42 to 2.44 - [Release notes](https://github.com/google/dagger/releases) - [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/dagger/compare/dagger-2.42...dagger-2.44) --- updated-dependencies: - dependency-name: com.google.dagger:hilt-android-gradle-plugin dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.dagger:dagger dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.dagger:dagger-compiler dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.dagger:hilt-android dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.dagger:hilt-android-testing dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.google.dagger:hilt-compiler dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index fd758dd859..c4dba43cf0 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -11,7 +11,7 @@ def gradle = "7.2.2" // Ref: https://kotlinlang.org/releases.html def kotlin = "1.7.10" def kotlinCoroutines = "1.6.4" -def dagger = "2.43.2" +def dagger = "2.44" def appDistribution = "16.0.0-beta04" def retrofit = "2.9.0" def arrow = "0.8.2" From b60bb295adb508a7cb8bb65cef5ba63c31b1035b Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Thu, 22 Sep 2022 09:38:20 +0000 Subject: [PATCH 009/136] Translated using Weblate (Catalan) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ca/ --- .../src/main/res/values-ca/strings.xml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) 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 863fa13fbb..25c490807e 100644 --- a/library/ui-strings/src/main/res/values-ca/strings.xml +++ b/library/ui-strings/src/main/res/values-ca/strings.xml @@ -2674,4 +2674,40 @@ Aquesta sessió està llesta per a missatges segurs. La teva sessió actual està llesta per a missatges segurs. Verifica la teva sessió actual obtenir missatges segurs millorats. + Crea missatge directe només al primer missatge + Activa missatges directes programats + Verifica o tanca aquesta sessió per estar més segur. + Per estar més segur, tanca qualsevol sessió que no reconeguis o ja no utilitzis. + No s\'han trobat sessions inactives. + No s\'han trobat sessions no verificades. + No s\'han trobat sessions verificades. + Detalls de sessió + Esborra filtre + Última activitat + Nom de la sessió + Informació d\'aplicació, dispositiu i activitat. + Adreça IP + + Pensa en tancar sessió de les sessions antigues (%1$d dia o més) que ja no utilitzis. + Pensa en tancar sessió de les sessions antigues (%1$d dies o més) que ja no utilitzis. + + Inactiu + No verificat + Verificat + Filtra + + Inactiu durant %1$d dia o més + Inactiu durant %1$d dies o més + + Inactiu + No verificat + Verificat + Totes les sessions + Filtre + Última activitat %1$s + Dispositiu + Sessió + Sessió actual + Element simplificat amb pestanyes opcionals + Activa la nova visualització \ No newline at end of file From 204f36dc3d07f49f8b12dd367a8e9ed5facc39ed Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Thu, 22 Sep 2022 08:53:08 +0000 Subject: [PATCH 010/136] Translated using Weblate (Czech) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- .../src/main/res/values-cs/strings.xml | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) 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 79f8311159..1983036271 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2720,4 +2720,48 @@ Sbalit podprostory %s Rozbalit podprostory %s Změnit prostor - + IP adresa + Poslední aktivita + Název relace + Informace o aplikacích, zařízeních a aktivitách. + Podrobnosti o relaci + Vyčistit filtr + Nebyly nalezeny žádné neaktivní relace. + Nebyly nalezeny žádné neověřené relace. + Nebyly nalezeny žádné ověřené relace. + + Zvažte odhlášení ze starých relací (%1$d den nebo více), které již nepoužíváte. + Zvažte odhlášení ze starých relací (%1$d dny nebo více), které již nepoužíváte. + Zvažte odhlášení ze starých relací (%1$d dnů nebo více), které již nepoužíváte. + + Neaktivní + Ověřte své relace pro vylepšené bezpečné zasílání zpráv nebo se odhlaste z těch, které již nepoznáváte nebo nepoužíváte. + Neověřeno + Pro nejlepší zabezpečení se odhlaste z každé relace, kterou již nepoznáváte nebo nepoužíváte. + Ověřeno + Filtr + + Neaktivní po dobu %1$d dne nebo déle + Neaktivní po dobu %1$d dnů nebo déle + Neaktivní po dobu %1$d dnů nebo déle + + Neaktivní + Není připraveno na bezpečné zasílání zpráv + Neověřeno + Připraveno na bezpečné zasílání zpráv + Ověřeno + Všechny relace + Filtr + Poslední aktivita %1$s + Zařízení + Relace + Aktuální relace + Pro nejlepší zabezpečení a spolehlivost tuto relaci ověřte nebo se z ní odhlaste. + Ověřte svou aktuální relaci pro vylepšené bezpečené zasílání zpráv. + Tato relace je připravena pro bezpečné zasílání zpráv. + Vaše aktuální relace je připravena pro bezpečné zasílání zpráv. + Vytvořit přímou zprávu pouze při první zprávě + Povolit odložené přímé zprávy + Zjednodušený Element s volitelnými kartami + Povolit nový vzhled + \ No newline at end of file From 589ccc142e3d8a67796b2e301eb2ea74d302eb21 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Thu, 22 Sep 2022 08:43:15 +0000 Subject: [PATCH 011/136] Translated using Weblate (Persian) Currently translated at 99.9% (2417 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/ --- library/ui-strings/src/main/res/values-fa/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 400a8121f9..9012bc2ebe 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2700,4 +2700,9 @@ ایجاد پیام خصوصی فقط در نخستین پیام المنتی ساده شده با زبانه‌های انتخابی به کار انداختن چینش جدید + تأیید نشست‌هایتان برای پیام‌رسانی امن بهبود یافته یا خروج از آن‌هایی که تشخیصشان نداده یا دیگر استفاده نمی‌کنید. + + غیرفعّال برای ۱ روز یا بیش‌تر + غیرفعّال برای %1$d روز یا بیش‌تر + \ No newline at end of file From ffa3e4b842728849b8ca55c886177a1b14b6f459 Mon Sep 17 00:00:00 2001 From: Glandos Date: Fri, 23 Sep 2022 12:02:14 +0000 Subject: [PATCH 012/136] Translated using Weblate (French) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- .../src/main/res/values-fr/strings.xml | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) 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 5a19ccf2da..c7100e3a1e 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2668,4 +2668,46 @@ Réduire %s enfants Développer %s enfants Changer d’espace - + Adresse IP + Dernière activité + Nom de la session + Application, appareil et information sur l’activité. + Détails de session + Supprimer les filtres + Aucune session inactive n’a été trouvée. + Aucune session non vérifiée n’a été trouvée. + Aucune session vérifiée n’a été trouvée. + + Pensez à vous déconnecter des anciennes sessions (%1$d jour ou plus) que vous n’utilisez plus. + Pensez à vous déconnecter des anciennes sessions (%1$d jours ou plus) que vous n’utilisez plus. + + Inactif + Vérifiez vos sessions pour améliorer la sécurité de votre messagerie, ou déconnectez celles que vous ne connaissez pas ou n’utilisez plus. + Non vérifié + Pour une meilleure sécurité, déconnectez toutes les sessions que vous ne connaissez pas ou que vous n’utilisez plus. + Vérifié + Filtrer + + Inactif depuis %1$d jour ou plus + Inactif depuis %1$d jours ou plus + + Inactif + Pas prêt pour une messagerie sécurisée + Non vérifié + Prêt pour une messagerie sécurisée + Vérifié + Toutes les sessions + Filtrer + Dernière activité %1$s + Appareil + Session + Cette session + Vérifiez ou déconnectez cette session pour une meilleure sécurité et fiabilité. + Vérifiez votre session pour une sécurité accrue de votre messagerie. + Cette session est prête pour l’envoi de messages sécurisés. + Votre session est prête pour l’envoi de messages sécurisés. + Créer la conversation seulement lors du premier message + Activer les conversations privées différées + Un Element simplifié avec des onglets optionnels + Activer la nouvelle présentation + \ No newline at end of file From 036620592618c95a1b8f232dd3dc89c0bcb7fea4 Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 23 Sep 2022 03:14:37 +0000 Subject: [PATCH 013/136] Translated using Weblate (Indonesian) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- .../src/main/res/values-in/strings.xml | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) 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 3b30950bd1..c608d82c85 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2618,4 +2618,44 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tutup %s anak Buka %s anak Buat Space - + Alamat IP + Aktivitas terakhir + Nama sesi + Informasi aplikasi, perangkat, dan aktivitas. + Detail sesi + Hapus Saringan + Tidak ditemukan sesi yang tidak aktif. + Tidak ditemukan sesi yang belum diverifikasi. + Tidak ditemukan sesi yang terverifikasi. + + Pertimbangkan untuk mengeluarkan sesi lawas (%1$d hari atau lebih) yang Anda tidak gunakan lagi. + + Tidak aktif + Verifikasi sesi Anda untuk perpesanan aman yang terbaik atau keluarkan sesi yang Anda tidak kenal atau gunakan lagi. + Belum diverifikasi + Untuk keamanan yang terbaik, keluarkan sesi yang Anda tidak kenal atau gunakan lagi. + Terverifikasi + Saring + + Tidak aktif selama %1$d hari atau lebih + + Tidak aktif + Belum siap untuk perpesanan aman + Belum diverifikasi + Siap untuk perpesanan aman + Terverifikasi + Semua sesi + Saring + Aktivitas terakhir %1$s + Perangkat + Sesi + Sesi Saat Ini + Verifikasi atau keluarkan sesi ini untuk keamanan dan keandalan yang terbaik. + Verifikasi sesi Anda saat ini untuk perpesanan aman yang baik. + Sesi ini siap untuk perpesanan aman. + Sesi Anda saat ini siap untuk perpesanan aman. + Buat pesan langsung hanya pada pesan pertama + Aktifkan pesan langsung tangguhan + Sebuah Element yang sederhana dengan fitur tab opsional + Aktifkan tata letak baru + \ No newline at end of file From 063b080d2cdf1968575645e11b1966b838cd5b6d Mon Sep 17 00:00:00 2001 From: random Date: Thu, 22 Sep 2022 14:02:12 +0000 Subject: [PATCH 014/136] Translated using Weblate (Italian) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- .../src/main/res/values-it/strings.xml | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) 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 b7b0fe91af..b2f9fa9238 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2659,4 +2659,46 @@ Riduci contenuto di %s Espandi contenuto di %s Cambia spazio - + Indirizzo IP + Ultima attività + Nome sessione + Applicazione, dispositivo e informazioni di attività. + Dettagli sessione + Annulla filtro + Nessuna sessione inattiva trovata. + Nessuna sessione non verificata trovata. + Nessuna sessione verificata trovata. + + Considera di disconnettere le sessioni vecchie (%1$d giorno o più) che non usi più. + Considera di disconnettere le sessioni vecchie (%1$d giorni o più) che non usi più. + + Inattivo + Verifica le tue sessioni per avere conversazioni più sicure o disconnetti quelle che non riconosci o che non usi più. + Non verificato + Per una maggiore sicurezza, disconnetti tutte le sessioni che non riconosci o che non usi più. + Verificato + Filtra + + Inattivo da %1$d giorno o più + Inattivo da %1$d giorni o più + + Inattivo + Non pronto per messaggi sicuri + Non verificato + Pronto per messaggi sicuri + Verificato + Tutte le sessioni + Filtra + Ultima attività %1$s + Dispositivo + Sessione + Sessione attuale + Verifica o disconnetti questa sessione per una migliore sicurezza e affidabilità. + Verifica la tua sessione attuale per messaggi più sicuri. + Questa sessione è pronta per i messaggi sicuri. + La tua sessione attuale è pronta per i messaggi sicuri. + Attiva messaggi diretti differiti + Crea messaggio diretto solo al primo messaggio + Un Element semplificato con schede opzionali + Attiva nuova disposizione + \ No newline at end of file From 06286e6a7a7fa9a9695cbd41f3f34b1a7bae0714 Mon Sep 17 00:00:00 2001 From: Didek Date: Thu, 22 Sep 2022 17:57:43 +0000 Subject: [PATCH 015/136] Translated using Weblate (Polish) Currently translated at 97.8% (2367 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- .../ui-strings/src/main/res/values-pl/strings.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 b7b73eb9e6..4109a130a5 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -2732,4 +2732,16 @@ Niestety, ten pokój nie został znaleziony. \nSpróbuj ponownie później.%s Zaproszenia - + Tutaj pojawią się rozmowy które nie zostały jeszcze odczytane. + Brak nowych wiadomości. + Zmień przestrzeń + Stwórz prywatny chat dopiero po wysłaniu pierwszej wiadomości + Włącz odroczone prywatne chaty + Odświeżony wygląd Element z opcjonalnymi kartami + Włącz nowy układ + Przestrzenie to nowa metoda na grupowanie razem wielu pokoi i osób. Dodaj tu już istniejący pokój lub stwórz nowy używając przycisku w prawym-dolnym rogu. + Jest to nowa metoda na grupowanie razem wielu pokoi i osób. + %s +\nwygląda nieco pusto. + Brak przestrzeni. + \ No newline at end of file From 2228ece79a2c04d79fb2a944aa736cd26c26aef4 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Fri, 23 Sep 2022 11:19:19 +0000 Subject: [PATCH 016/136] Translated using Weblate (Russian) Currently translated at 97.3% (2356 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- .../src/main/res/values-ru/strings.xml | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) 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 7c9d073035..e0ab799a57 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -956,11 +956,11 @@ Изменения не найдены Отфильтровать беседы… Не можете найти нужное\? - Создать новую комнату - Отправить новое личное сообщение + Создать комнату + Отправить личное сообщение Просмотр каталога комнат Имя или ID (#example:matrix.org) - Включить жест смахивания для ответа в ленте сообщений + Жест смахивания для ответа в ленте сообщений Ссылка скопирована в буфер обмена Создаем комнату… История изменений @@ -2435,7 +2435,7 @@ Не удалось загрузить карту Карта Примечание: приложение будет перезапущено - Включить обсуждения сообщений + Обсуждения сообщений Подключиться к серверу Хотите присоединиться к существующему серверу\? Пропустить вопрос @@ -2666,7 +2666,7 @@ Создать беседу или комнату Показать все сессии (V2, в разработке) Люди - Настройки макета + Настройки оформления Фильтры Недавние Избранные @@ -2693,4 +2693,23 @@ Добро пожаловать в ${app_name}, \n%s. Оставить отзыв - + Название сессии + Неактивные + IP-адрес + Последняя активность + Сведения о сессии + Для лучшей безопасности выйдите из всех сессий, которые более не признаёте или не используете. + Заверено + Все сессии + Последняя активность %1$s + Устройство + Сессия + Текущая сессия + Заверить сессию + Подробности + Эта сессия готова к безопасному обмену сообщениями. + Текущая сессия готова к безопасному обмену сообщениями. + Веб-браузер + Пространства — это новый способ организации комнат и людей. Создайте пространство, чтобы начать. + Новое оформление + \ No newline at end of file From c0b854f54f492c4d700cdd465d84ded0760c3d5a Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Thu, 22 Sep 2022 23:45:15 +0000 Subject: [PATCH 017/136] Translated using Weblate (Slovak) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- .../src/main/res/values-sk/strings.xml | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) 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 9eb22e3ae3..f37af1a654 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2720,4 +2720,48 @@ Zbaliť %s podpriestory Rozbaliť %s podpriestory Zmeniť priestor - + IP adresa + Posledná aktivita + Názov relácie + Informácie o aplikácii, zariadení a činnosti. + Podrobnosti o relácii + Zrušiť filter + Nenašli sa žiadne neaktívne relácie. + Nenašli sa žiadne neoverené relácie. + Nenašli sa žiadne overené relácie. + + Zvážte odhlásenie zo starých relácií (%1$d deň alebo viac), ktoré už nepoužívate. + Zvážte odhlásenie zo starých relácií (%1$d dni alebo viac), ktoré už nepoužívate. + Zvážte odhlásenie zo starých relácií (%1$d dní alebo viac), ktoré už nepoužívate. + + Neaktívne + Overte si relácie pre vylepšené bezpečné zasielanie správ alebo sa odhláste z tých, ktoré už nepoznáte alebo nepoužívate. + Neoverené + V záujme čo najlepšieho zabezpečenia sa odhláste z každej relácie, ktorú už nepoznáte alebo nepoužívate. + Overené + Filter + + Neaktívny už %1$d deň alebo dlhšie + Neaktívny už %1$d dni alebo dlhšie + Neaktívny už %1$d dní alebo dlhšie + + Neaktívne + Nie je pripravené na bezpečné zasielanie správ + Neoverené + Pripravené na bezpečné zasielanie správ + Overené + Všetky relácie + Filter + Posledná aktivita %1$s + Zariadenie + Relácia + Aktuálna relácia + V záujme čo najvyššej bezpečnosti a spoľahlivosti túto reláciu overte alebo sa z nej odhláste. + Overte svoju aktuálnu reláciu pre vylepšené bezpečné zasielanie správ. + Táto relácia je pripravená na bezpečné zasielanie správ. + Vaša aktuálna relácia je pripravená na bezpečné zasielanie správ. + Vytvoriť priamu správu len pri prvej správe + Povoliť odložené priame správy + Zjednodušený Element s voliteľnými kartami + Zapnúť nové usporiadanie + \ No newline at end of file From 2a8dfc2a599141f31e1d653d58ddbb2cb4547c03 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 22 Sep 2022 18:54:23 +0000 Subject: [PATCH 018/136] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- .../src/main/res/values-uk/strings.xml | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) 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 3e511f8459..41626bd156 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2772,4 +2772,50 @@ Згорнути дочірні елементи %s Розгорнути дочірні елементи %s Змінити простір - + IP-адреса + Остання активність + Назва сеансу + Відомості про застосунок, пристрій та діяльність. + Подробиці сеансу + Очистити фільтр + Неактивних сеансів не знайдено. + Не знайдено не звірених сеансів. + Знайдені не звірені сеанси. + + Подумайте про те, щоб вийти зі старих сеансів (%1$d день або довше), якими ви більше не користуєтесь. + Подумайте про те, щоб вийти зі старих сеансів (%1$d дні або довше), якими ви більше не користуєтесь. + Подумайте про те, щоб вийти зі старих сеансів (%1$d днів або довше), якими ви більше не користуєтесь. + Подумайте про те, щоб вийти зі старих сеансів (%1$d днів або довше), якими ви більше не користуєтесь. + + Неактивний + Звірте свої сеанси для посилення безпеки обміну повідомленнями або вийдіть з тих, які ви більше не впізнаєте або не використовуєте. + Не звірений + Для кращої безпеки виходьте з будь-якого сеансу, який ви більше не впізнаєте або не використовуєте. + Звірений + Фільтрувати + + Неактивний %1$d день або довше + Неактивний %1$d дні або довше + Неактивний %1$d днів або довше + Неактивний %1$d днів або довше + + Неактивний + Не готовий до безпечного обміну повідомленнями + Не звірений + Звірений + Готовий до безпечного обміну повідомленнями + Усі сеанси + Фільтрувати + Остання активність %1$s + Пристрій + Сеанс + Поточний сеанс + Звірте або вийдіть з цього сеансу для кращої безпеки та надійності. + Звірте свій поточний сеанс для посилення безпеки обміну повідомленнями. + Цей сеанс готовий до безпечного обміну повідомленнями. + Ваш поточний сеанс готовий до безпечного обміну повідомленнями. + Створюйте приватні повідомлення лише за надсилання першого повідомлення + Увімкнути відкладені приватні повідомлення + Спрощений Element з опціональними вкладками + Увімкнути новий вигляд + \ No newline at end of file From f415a7f5db5fac74f18de40f06b98b0c24119db9 Mon Sep 17 00:00:00 2001 From: phardyle Date: Thu, 22 Sep 2022 16:52:31 +0000 Subject: [PATCH 019/136] Translated using Weblate (Chinese (Simplified)) Currently translated at 98.1% (2375 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/ --- library/ui-strings/src/main/res/values-zh-rCN/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 db1dab92e2..69a2fc5eef 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 @@ -2604,4 +2604,7 @@ 提供反馈 点击右上角查看反馈选项。 试用 - + 空间是对房间和人进行分组的新方式。创建一个空间来开始吧。 + 启用新布局 + IP地址 + \ No newline at end of file From c0504a20022c8c8ba4a75522338de460dc876757 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 23 Sep 2022 01:55:02 +0000 Subject: [PATCH 020/136] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- .../src/main/res/values-zh-rTW/strings.xml | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) 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 78caa2cc2e..876084d566 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 @@ -2616,4 +2616,44 @@ 折疊 %s 個子空間 展開 %s 個子空間 變更空間 - + IP 位置 + 最後活動 + 工作階段名稱 + 應用程式、裝置與活動資訊。 + 工作階段詳細資訊 + 清除過濾條件 + 找不到不活躍的工作階段。 + 找不到未驗證的工作階段。 + 找不到已驗證的工作階段。 + + 閒置%1$d天或更久 + + + 考慮登出您不再使用的舊工作階段(%1$d天或更久)。 + + 不活躍 + 驗證您的工作階段以強化安全通訊或從您無法識別或不再使用的工作階段登出。 + 未驗證 + 為取得最佳安全性,請從任何您無法識別或不再使用的工作階段登出。 + 已驗證 + 過濾 + 不活躍 + 尚未準備好安全通訊 + 未驗證 + 準備好安全通訊 + 已驗證 + 所有工作階段 + 過濾 + 最後活動 %1$s + 裝置 + 工作階段 + 目前的工作階段 + 驗證或從此工作階段登出以取得最佳安全性與可靠性。 + 驗證您目前的工作階段以強化安全通訊。 + 此工作階段已準備好安全通訊。 + 您目前的工作階段已準備好安全通訊。 + 僅在第一則訊息上建立直接訊息 + 啟用延期直接訊息 + 包含選擇性分頁的簡潔 Element + 啟用新佈局 + \ No newline at end of file From ab7dc527faa176ac778e91abfaf9e5abbab22c38 Mon Sep 17 00:00:00 2001 From: Vri Date: Thu, 22 Sep 2022 10:05:50 +0000 Subject: [PATCH 021/136] Translated using Weblate (German) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/de/ --- fastlane/metadata/android/de-DE/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40104360.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40104360.txt b/fastlane/metadata/android/de-DE/changelogs/40104360.txt new file mode 100644 index 0000000000..bf249af068 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Das neue App-Layout kann in den Labor-Einstellungen aktiviert werden. Probier es gerne aus! +Fehler bzgl. ausbleibender Benachrichtigungen und langwierigem inkrementellem Synchronisieren behoben. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From 15a027d7fd0804f21c9ae2ca13dfc394d6e3faa0 Mon Sep 17 00:00:00 2001 From: Glandos Date: Fri, 23 Sep 2022 11:55:28 +0000 Subject: [PATCH 022/136] Translated using Weblate (French) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/ --- fastlane/metadata/android/fr-FR/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40104360.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104360.txt b/fastlane/metadata/android/fr-FR/changelogs/40104360.txt new file mode 100644 index 0000000000..80f59952d1 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104360.txt @@ -0,0 +1,3 @@ +La nouvelle présentation de l’application est disponibles dans les paramètres expérimentaux. Essayez-là ! +Correction de problèmes sur les notifications manquantes, et la synchronisation incrémentale lente. +Intégralité des changements : https://github.com/vector-im/element-android/releases From 9a438204c4169ecdd83d678867693505660192a3 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Thu, 22 Sep 2022 23:35:37 +0000 Subject: [PATCH 023/136] Translated using Weblate (Slovak) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40104360.txt diff --git a/fastlane/metadata/android/sk/changelogs/40104360.txt b/fastlane/metadata/android/sk/changelogs/40104360.txt new file mode 100644 index 0000000000..af4154b5cf --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Nové usporiadanie aplikácie môžete povoliť v nastaveniach laboratórií. Vyskúšajte to! +Oprava problémov týkajúcich sa chýbajúcich oznámení a dlhej inkrementálnej synchronizácie. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From 4a752f7f43d0a08154c6a6978f5a42a0c432fcfb Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 22 Sep 2022 18:20:11 +0000 Subject: [PATCH 024/136] Translated using Weblate (Ukrainian) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40104360.txt diff --git a/fastlane/metadata/android/uk/changelogs/40104360.txt b/fastlane/metadata/android/uk/changelogs/40104360.txt new file mode 100644 index 0000000000..a2c9bcc4b5 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Новий макет програми можна увімкнути в налаштуваннях лабораторії. Спробуйте! +Виправлено проблеми з відсутністю сповіщень та тривалою інкрементною синхронізацією. +Список усіх змін: https://github.com/vector-im/element-android/releases From e749831ad1bdc642b8891794f5562417840e126b Mon Sep 17 00:00:00 2001 From: random Date: Thu, 22 Sep 2022 14:04:29 +0000 Subject: [PATCH 025/136] Translated using Weblate (Italian) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/it/ --- fastlane/metadata/android/it-IT/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40104360.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40104360.txt b/fastlane/metadata/android/it-IT/changelogs/40104360.txt new file mode 100644 index 0000000000..c6749d3ff7 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Nuova disposizione dell'app attivabile nelle impostazioni Laboratori. Provala! +Corretti problemi su notifiche mancanti e sincronizzazioni incrementali lunghe. +Cronologia completa: https://github.com/vector-im/element-android/releases From f45209d19719d950208122096fee312defd48adc Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Thu, 22 Sep 2022 08:41:20 +0000 Subject: [PATCH 026/136] Translated using Weblate (Persian) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40104360.txt diff --git a/fastlane/metadata/android/fa/changelogs/40104360.txt b/fastlane/metadata/android/fa/changelogs/40104360.txt new file mode 100644 index 0000000000..be14e1b9e2 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104360.txt @@ -0,0 +1,3 @@ +چینش کارهٔ جدید می‌تواند در تنظیمات آزمایشگاه‌ها به کار بیفتند. لطفاً بیازماییدش! +رفع مشکلات مربوط به آگاهی غایب و همگام‌سازی تجمعّی طولانی. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From dc9c0ce573dec4fa4ac02ff5a069118f0a246a5f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 23 Sep 2022 01:45:49 +0000 Subject: [PATCH 027/136] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/ --- fastlane/metadata/android/zh-TW/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40104360.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104360.txt b/fastlane/metadata/android/zh-TW/changelogs/40104360.txt new file mode 100644 index 0000000000..be36b60840 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104360.txt @@ -0,0 +1,3 @@ +新的應用程式佈局可在「實驗室」設定中啟用。請試試看! +修復關於遺失通知的問題,以及增量同步需要長時間的問題。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From a71cc768f557d75d4f8f73cb14de93a9fbe4df72 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Thu, 22 Sep 2022 08:43:07 +0000 Subject: [PATCH 028/136] Translated using Weblate (Czech) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/ --- fastlane/metadata/android/cs-CZ/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40104360.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104360.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104360.txt new file mode 100644 index 0000000000..fcadf9898c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Nový vzhled aplikace lze povolit v Experimentálních funkcích. Prosíme, vyzkoušejte ho! +Oprava problémů s chybějícími oznámeními a dlouhou přírůstkovou synchronizací. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From 13bca69ae4934142827cf13b88d4edae21f80c05 Mon Sep 17 00:00:00 2001 From: Linerly Date: Thu, 22 Sep 2022 09:07:24 +0000 Subject: [PATCH 029/136] Translated using Weblate (Indonesian) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40104360.txt diff --git a/fastlane/metadata/android/id/changelogs/40104360.txt b/fastlane/metadata/android/id/changelogs/40104360.txt new file mode 100644 index 0000000000..be626f6350 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Tata Letak Aplikasi Baru dapat diaktifkan di pengaturan Uji Coba. Cobalah! +Perbariki masalah tentang notifikasi hilang, dan penyinkronan inkremental panjang. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From b356ac799a6f4fedbcfcbf0418c7ecb805dfb84c Mon Sep 17 00:00:00 2001 From: Vri Date: Sat, 24 Sep 2022 14:54:39 +0000 Subject: [PATCH 030/136] Translated using Weblate (German) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- .../src/main/res/values-de/strings.xml | 160 +++++++++++++----- 1 file changed, 115 insertions(+), 45 deletions(-) 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 e01fc898a3..5154809f72 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -269,7 +269,7 @@ Problem melden Bitte beschreibe das Problem. Was hast du genau gemacht\? Was sollte passieren\? Was ist tatsächlich passiert\? Problembeschreibung - Um Probleme diagnostizieren zu können, werden Protokolle des Clients zusammen mit dem Fehlerbericht übermittelt. Dieser Fehlerbericht wird, wie die Protokolle und das Bildschirmfoto, nicht öffentlich sichtbar sein. Wenn du nur den oben eingegebenen Text senden möchtest, die nachfolgenden Haken entsprechend entfernen: + Um Probleme diagnostizieren zu können, werden Protokolle der Anwendung zusammen mit dem Fehlerbericht übermittelt. Dieser Fehlerbericht wird, wie die Protokolle und das Bildschirmfoto, nicht öffentlich sichtbar sein. Wenn du nur den oben eingegebenen Text senden möchtest, die nachfolgenden Haken entsprechend entfernen: Du scheinst dein Telefon frustriert zu schütteln. Möchtest du das Fenster zum Senden eines Fehlerberichts öffnen\? Dein Fehlerbericht wurde erfolgreich übermittelt Der Fehlerbericht konnte nicht übermittelt werden (%s) @@ -356,7 +356,7 @@ Benachrichtigungen für diesen Account Benachrichtigungen für diese Sitzung Direktnachrichten - Gruppenchats + Gruppenunterhaltungen Einladungen Anrufe Nachrichten von Bots @@ -403,8 +403,8 @@ Alle Nachrichten von %s anzeigen\? Wähle ein Land Thema - Lesbarkeit des Chatverlaufs - Wer kann den Chatverlauf lesen? + Lesbarkeit des Verlaufs + Wer kann den Verlauf lesen\? Alle Nur Mitglieder Nur Mitglieder (ab Einladung) @@ -447,7 +447,7 @@ Starte beim Systemstart Medien-Cache leeren Medien behalten - Für alle Nachrichten Zeitstempel anzeigen + Zeitstempel für alle Nachrichten 3 Tage 1 Woche 1 Monat @@ -500,7 +500,7 @@ Sicher, dass du einen Videoanruf starten möchtest\? Die Verbannung einer Person entfernt sie aus diesem Raum und hindert sie am erneuten Beitritt. Alle Nachrichten - URL-Vorschau im Chat + URL-Vorschau Vibriere beim Erwähnen eines Nutzers Erstellen Startseite @@ -605,7 +605,7 @@ %1$s: %2$s +%d Aus Unterhaltung entfernen - Linkvorschau im Chat aktivieren, falls dein Homeserver diese Funktion unterstützt. + Link-Vorschau im Chat aktivieren, falls dein Heim-Server diese Funktion unterstützt. Schreibbenachrichtigungen senden Lasse andere Benutzer wissen, dass du tippst. Markdown-Formatierung @@ -729,10 +729,10 @@ Wiederherstellungsschlüssel aus Passphrase generieren. Dies kann mehrere Sekunden brauchen. Du verlierst möglicherweise den Zugang zu deinen Nachrichten, wenn du dich abmeldest oder das Gerät verlierst. Rufe Backup-Version ab… - Nutze deine Wiederherstellungspassphrase, um deinen verschlüsselten Chatverlauf lesen zu können + Nutze deine Wiederherstellungs-Passphrase, um deinen verschlüsselten Nachrichtenverlauf lesen zu können nutze deinen Wiederherstellungsschlüssel Wenn du deine Wiederherstellungspassphrase nicht weist, kannst du %s. - Nutze deinen Wiederherstellungsschlüssel, um deinen verschlüsselten Chatverlauf lesen zu können + Nutze deinen Wiederherstellungsschlüssel, um deinen verschlüsselten Nachrichtenverlauf lesen zu können Hast du deinen Wiederherstellungsschlüssel verloren\? Du kannst einen neuen in den Einstellungen einrichten. Sicherung konnte mit dieser Passphrase nicht entschlüsselt werden. Bitte stelle sicher, dass du die korrekte Wiederherstellungspassphrase eingegeben hast. Gib deinen Wiederherstellungsschlüssel ein @@ -757,7 +757,7 @@ Die Sicherung hat eine ungültige Signatur von der verifizierten Sitzung %s Die Sicherung hat eine ungültige Signatur von der nicht verifizierten Sitzung %s Um die Schlüsselsicherung für diese Sitzung zu verwenden, stelle sie jetzt mit deiner Passphrase oder deinem Wiederherstellungsschlüssel wieder her. - Deine gesicherten Schlüssel vom Server löschen\? Du wirst deinen Wiederherstellungsschlüssel nicht mehr nutzen können, um deinen verschlüsselten Chatverlauf zu lesen. + Deine gesicherten Schlüssel vom Server löschen\? Du wirst deinen Wiederherstellungsschlüssel nicht mehr nutzen können, um deinen verschlüsselten Nachrichtenverlauf zu lesen. Beim Abmelden gehen deine verschlüsselten Nachrichten verloren Schlüssel-Sicherung wird durchgeführt. Wenn du dich jetzt abmeldest, gehen deine verschlüsselten Nachrichten verloren. Schlüsselsicherung sollte bei allen Sitzungen aktiviert sein, um den Verlust verschlüsselter Nachrichten zu verhindern. @@ -889,7 +889,7 @@ Sonstige Hinweise Dritter Du siehst diesen Raum bereits! Allgemein - Einstellungen + Optionen Sicherheit und Privatsphäre Push-Regeln Keine Push-Regeln definiert @@ -1004,7 +1004,7 @@ Navigationsmenü öffnen Raumerstellungsmenü öffnen Schließe das Raumerstellungsmenü… - Starte einen neuen Privatchat + Erstelle eine neue Direktnachricht Erstelle einen neuen Raum Schließe Key-Backup-Einblendung Zum Ende springen @@ -1052,7 +1052,7 @@ Halte auf einem Raum um mehr Optionen anzuzeigen %1$s hat den Raum für jeden, der den Link hat, öffentlich gemacht. Ungelesene Nachrichten - Privat oder in Gruppen mit Leuten chatten + Schreibe privat oder in Gruppen Halte Gespräche mittels Verschlüsselung privat Los geht\'s Wähle einen Server @@ -1081,13 +1081,13 @@ Es tut uns leid. Dieser Server akzeptiert keine neuen Benutzerkonten. Die Anwendung kann kein neues Benutzerkonto auf diesem Server erstellen. \n -\nMöchtest du dich über eine Web-Anwendung anmelden\? +\nMöchtest du dich mit einer Web-Anwendung anmelden\? Diese E-Mail-Adresse ist mit keinem Benutzerkonto verknüpft. Passwort auf %1$s zurücksetzen E-Mail Neues Passwort Achtung! - Eine Änderung deines Passworts wird alle Ende-zu-Ende-Schlüssel zurücksetzen. Dein verschlüsselter Chatverlauf wird dadurch unlesbar. Richte die Schlüsselsicherung ein oder exportiere deine Raumschlüssel aus einer anderen Sitzung, bevor du dein Passwort zurücksetzt. + Eine Änderung deines Passworts wird alle Ende-zu-Ende-Schlüssel zurücksetzen. Dein verschlüsselter Verlauf wird dadurch unlesbar. Richte die Schlüsselsicherung ein oder exportiere deine Raumschlüssel aus einer anderen Sitzung, bevor du dein Passwort zurücksetzt. Fortfahren Diese E-Mail-Adresse ist mit keinem Benutzerkonto verknüpft Prüfe deinen Posteingang @@ -1126,9 +1126,9 @@ Es ist deine Konversation. Mache sie dir zu eigen. Premium-Hosting für Organisationen Gib die Adresse des Modular Element oder Servers ein, den du verwenden möchtest - Die Anwendung kann sich nicht bei diesem Homeserver anmelden. Der Homeserver unterstützt die folgenden Anmeldemöglichkeiten: %1$s. + Die Anwendung kann sich nicht bei diesem Heim-Server anmelden. Der Heim-Server unterstützt die folgenden Anmeldemöglichkeiten: %1$s. \n -\nMöchtest du dich mit einem Webclient anmelden\? +\nMöchtest du dich mit einer Web-Anwendung anmelden\? Dir wird eine Bestätigungsmail gesendet, um dein neues Passwort zu bestätigen. Weiter Du wurdest von allen Sitzungen abgemeldet und erhältst keine Push-Benachrichtigungen mehr. Um Benachrichtigungen wieder zu aktivieren, melde dich auf jedem Gerät erneut an. @@ -1373,7 +1373,7 @@ Import der Schlüssel fehlgeschlagen Benachrichtigungskonfiguration Nachrichten mit \"@room\" - Verschlüsselte Gruppenchats + Verschlüsselte Gruppenunterhaltungen Sendet eine Nachricht als einfachen Text, ohne sie als Markdown zu interpretieren Inkorrekter Benutzername und/oder Passwort. Das eingegebene Passwort beginnt oder endet mit Leerzeichen, bitte kontrolliere es. Nachrichtenschlüssel @@ -1381,7 +1381,7 @@ Druck es aus und speichere es an einem sicheren Ort Kopier es in deinen persönlichen Cloud-Speicher Verschlüsselung ist nicht aktiviert - Raumupgrades + Raumaktualisierung Verschlüsselung aktiviert Nachrichten in diesem Raum sind Ende-zu-Ende-verschlüsselt. Erfahre mehr und verifiziere Benutzer in deren Profil. Die Verschlüsselung in diesem Raum wird nicht unterstützt @@ -1392,7 +1392,7 @@ Fast geschafft! Warte auf Bestätigung… Verschlüsselte Direktnachrichten Nachricht… - Verifiziere dich und andere, um eure Chats zu schützen + Verifiziere dich und andere, um eure Unterhaltungen zu schützen Gib zum Fortfahren deinen %s ein Datei benutzen Dies ist kein gültiger Wiederherstellungsschlüssel @@ -1412,12 +1412,12 @@ Bildschirmfotos der Anwendung verhindern Das Aktivieren dieser Einstellung setzt FLAG_SECURE in allen Aktivitäten. Starte die Anwendung neu, damit die Änderung wirksam wird. Neues Benutzerpasswort festlegen… - Nutze die neueste Version von ${app_name} auf deinen anderen Geräten, ${app_name} Web, ${app_name} Desktop, ${app_name} iOS, ${app_name} für Android oder einen anderen cross-signing-fähigen Matrix-Client + Nutze die neueste Version von ${app_name} auf deinen anderen Geräten, ${app_name} Web, ${app_name} Desktop, ${app_name} iOS, ${app_name} für Android oder eine andere Matrix-Anwendung, die Quersignierung unterstützt ${app_name} Web \n${app_name} Desktop ${app_name} iOS \n${app_name} Android - oder einen anderen cross-signing-fähigen Matrix Client + oder eine andere Matrix-Anwendung, die Quersignierung unterstützt Nutze die neueste Version von ${app_name} auf deinen anderen Geräten: Erzwingt das Verwerfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum Wird nur in verschlüsselten Räumen unterstützt @@ -1570,7 +1570,7 @@ Bestätigen Lege Rolle fest Rolle - Öffne Chat + Unterhaltung öffnen Stelle Mikrophon stumm Aktiviere Mikrophon Stoppe Kamera @@ -1704,7 +1704,7 @@ Alle Wiederherstellungsoptionen vergessen oder verloren\? Alles zurücksetzen Du bist beigetreten. %s ist beigetreten. - Nachrichten in diesem Raum sind Ende-zu-Ende-verschlüsselt. + Nachrichten in dieser Unterhaltung sind Ende-zu-Ende-verschlüsselt. Verlassen Einstellungen Nachrichten hier sind Ende-zu-Ende-verschlüsselt. @@ -1744,7 +1744,7 @@ Direktnachricht Verlauf der Anfragen von Schlüsselfreigaben senden Keine weiteren Ergebnisse - Beginne ein Gespräch + Beginne eine Unterhaltung Autorisieren Meine Zustimmung widerrufen Du hast zugestimmt E-Mails und Telefonnummern an diesen Identitätsserver zu senden, um von anderen Nutzern entdeckt zu werden. @@ -1774,7 +1774,7 @@ Suche nach Kontakten auf Matrix Raumbild einrichten Einverständnis wurde nicht abgegeben. - Teile diesen Code mit Leuten, damit sie ihn scannen und mit dir chatten können. + Teile diesen Code, damit andere ihn einlesen und mit dir schreiben können. Meinen Code teilen Mein Code Scanne einen QR-Code @@ -1849,7 +1849,7 @@ Knopf zum Nachrichteneditor hinzufügen, der die Emoji-Tastatur öffnet Emoji-Tastatur anzeigen Nutze /confetti oder sende Nachrichten mit ❄️ oder 🎉 - Chateffekte + Effekte im Verlauf Thema ändern Raum aktualisieren Rollen, die zum Ändern verschiedener Teile des Raums erforderlich sind, auswählen @@ -1960,7 +1960,7 @@ Diese werden in der Lage sein, %s zu durchsuchen Diese werden kein Teil von %s sein Tritt meinem Space %1$s %2$s bei - Mit Spaces kannst du Personen und Räume gruppieren. + Spaces sind eine neue Möglichkeit, Räume und Personen zu gruppieren. Räume oder Spaces hinzufügen Vorübergehend überspringen Über welche Themen möchtest du dich in %s unterhalten\? @@ -2051,7 +2051,7 @@ Privater Space Öffentlicher Space Unbekannte Person - Feedback geben + Rückmeldung geben Fehler beim Senden vom Feedback (%s) Dein Feedback wurde erfolgreich versandt. Danke! Mich bei Fragen kontaktieren @@ -2105,14 +2105,14 @@ Sprachnachricht Lege fest, wer diesen Raum finden und betreten kann. Klicke, um die Spaces zu bearbeiten - Spaces auswählen + Spaces wählen Mitglieder von %s können Räume finden, betrachten und betreten. Privat (Zutritt nur mit Einladung) Raumupgrades Nachrichten von Bots Raumeinladungen - Verschlüsselten Gruppenchats - Gruppenchats + Verschlüsselte Gruppennachrichten + Gruppennachrichten Verschlüsselten Direktnachrichten Direktnachrichten Mein Benutzername @@ -2268,7 +2268,7 @@ Hilfe und Unterstützung Hilfe Rechtliches - Entscheide, welche Spaces Zugriff auf den Raum haben sollen. Die Mitglieder der Spaces können diesen Räumen beitreten. + Entscheide, welche Spaces Zugriff auf den Raum haben sollen. Die Mitglieder der Spaces können diesen Räumen betreten. hier Hilf mit, ${app_name} zu verbessern Aktivieren @@ -2363,10 +2363,10 @@ Communities Teams Wir helfen dir, in Verbindung zu kommen - Mit wem wirst du am meisten chatten\? + Mit wem wirst du am meisten schreiben\? Link zu Thread kopieren Threads anzeigen - Nachrichtenblasen anzeigen + Nachrichtenblasen Laden der Karte fehlgeschlagen Karte Hinweis: App wird neugestartet @@ -2409,19 +2409,19 @@ Threads nähern sich der Beta 🎉 Deaktivieren BETA - Feedback geben + Rückmeldung geben BETA Threads Beta Threads Beta Bildschirm teilen - Ausprobieren + Probiere es aus Live bis %1$s Wähle Deine Benachrichtigungsmethode Vorläufige Implementierung: Standorte bleiben im Nachrichtenverlauf von Räumen erhalten Profil-Tag: h Standortfreigabe aktivieren - Bitte beachten: Dies ist eine Testfunktion mit einer vorübergehenden Implementierung. Das bedeutet, dass Du Deinen Standortverlauf nicht löschen kannst und dass fortgeschrittene Nutzer Deinen Standortverlauf auch dann noch sehen können, wenn Du Deinen Live-Standort nicht mehr mit diesem Raum teilst. + Bitte beachte: Dies ist eine experimentelle Funktion, die eine temporäre Implementierung nutzt. Das bedeutet, dass du deinen Standortverlauf nicht löschen kannst und erfahrene Nutzer ihn sehen können, selbst wenn du deinen Live-Standort nicht mehr mit diesem Raum teilst. Live-Standortfreigabe Aktuelles Gateway: %s Gateway @@ -2464,7 +2464,7 @@ %1$d Minuten %2$d Sekunden %1$s, %2$s, %3$s Die neuesten Profilinformationen (Avatar und Anzeigename) für alle Nachrichten anzeigen. - Aktuelle Benutzerinformationen anzeigen + Aktuelle Profilinformationen Sieht gut aus! einen Anzeigenamen wählen Zurück zum Home-Screen @@ -2521,7 +2521,7 @@ Profil personalisieren ${app_name} ist auch für den Arbeitsplatz geeignet. Die sichersten Organisationen der Welt vertrauen darauf. Threads sind noch in Arbeit, und es stehen neue, aufregende Funktionen an, wie z. B. verbesserte Benachrichtigungen. Wir würden uns sehr über Dein Feedback freuen! - Nachrichten in diesem Chat werden Ende-zu-Ende-verschlüsselt. + Nachrichten in dieser Unterhaltung werden Ende-zu-Ende-verschlüsselt. Bist du ein Mensch\? Bitte lies dir %ss Bedingungen und Richtlinien durch Server-Richtlinien @@ -2585,7 +2585,7 @@ Raum erstellen Ungelesene Personen - Schreibe deine erste Nachricht, um %s zur Konversation einzuladen + Schreibe deine erste Nachricht, um %s zur Unterhaltung einzuladen Alle Sitzungen anzeigen (V2, in Arbeit) Für bestmögliche Sicherheit verifiziere deine Sitzungen und melde dich von allen ab, die du nicht erkennst oder nutzt. Andere Sitzungen @@ -2619,7 +2619,7 @@ Entschuldigung, dieser Raum wurde nicht gefunden. \nBitte versuche es später erneut.%s Einladungen - Nicht verifiziert · Letzte Aktivität %1$s + Nicht verifiziert · Neueste Aktivität %1$s Nicht verifizierte Sitzung Nicht verifizierte Sitzung Verbessere deine Kontosicherheit, indem du diese Empfehlungen beherzigst. @@ -2628,15 +2628,85 @@ Inaktiv seit %1$d+ Tag (%2$s) Inaktiv seit %1$d+ Tagen (%2$s) - Verifiziert · Letzte Aktivität %1$s + Verifiziert · Neueste Aktivität %1$s Verifizierte Sitzung Unbekannter Gerätetyp Nichts Neues. - Spaces sind eine neue Art, Räume und Personen zu organisieren. Erstelle einen Space, um zu beginnen. + Spaces sind eine neue Möglichkeit, Räume und Personen zu gruppieren. Erstelle einen Space, um zu beginnen. Noch keine Spaces. Hier werden deine ungelesenen Nachrichten erscheinen, wenn du welche hast. Es gibt nichts Neues. Alle Unterhaltungen Space wechseln Unterhaltung beginnen - + Filter + Filtern + Subspaces von %s schließen + Subspaces von %s erweitern + Andere können dich als %s finden + Erstelle Unterhaltungen mit der ersten Nachricht + Verzögerte Direktnachrichten + Historie anzeigen + Probiere es aus + Tippe oben rechts, um eine Rückmeldung zu senden. + Rückmeldung geben + Greife auf deine Spaces (unten rechts) schneller und einfacher denn je zu. + Auf Spaces zugreifen + Um dein ${app_name} zu vereinfachen, sind Tabs nun optional. Verwalte sie mit dem Menü oben rechts. + Willkommen in einer neuen Übersicht! + Die Komplettlösung für sichere Kommunikation unter Freunden, in Gruppen oder in Organisationen. Erstelle eine Unterhaltung oder trete einem bestehenden Raum bei, um loszulegen. + Willkommen bei ${app_name}, +\n%s. + Spaces sind eine neue Möglichkeit, Räume und Personen zu gruppieren. Füge einen bestehenden Raum hinzu oder erstelle einen neuen mit der Schaltfläche unten rechts. + %s +\nsieht ein bisschen leer aus. + IP-Adresse + Sitzungsname + Anwendung, Gerät und Aktivitätsinformationen. + Sitzungsdetails + Filter zurücksetzen + Keine inaktiven Sitzungen gefunden. + Keine nicht verifizierten Sitzungen gefunden. + Keine verifizierten Sitzungen gefunden. + + Erwäge, dich aus alten Sitzungen (%1$d Tag oder mehr) abzumelden, die du nicht mehr benutzt. + Erwäge, dich aus alten Sitzungen (%1$d Tage oder mehr) abzumelden, die du nicht mehr benutzt. + + Inaktiv + Für besonders sichere Kommunikation verifiziere deine Sitzungen oder melde dich von ihnen ab, falls du sie nicht mehr identifizieren kannst. + Nicht verifiziert + Verifiziert + + Inaktiv seit %1$d Tag oder länger + Inaktiv seit %1$d Tagen oder länger + + Inaktiv + Nicht bereit für sichere Kommunikation + Nicht verifiziert + Für sichere Kommunikation bereit + Verifiziert + Alle Sitzungen + Gerät + Sitzung + Aktuelle Sitzung + + Erwäge, dich aus alten (%1$d Tag oder mehr), nicht mehr verwendeten Sitzungen abzumelden. + Erwäge, dich aus alten (%1$d Tage oder mehr), nicht mehr verwendeten Sitzungen abzumelden. + + Inaktive Sitzungen + Nicht verifizierte Sitzungen verifizieren oder abmelden. + Alle anzeigen (%1$d) + Sitzung verifizieren + Diese Sitzung ist für sichere Kommunikation bereit. + Desktop + Hier erscheinen deine neuen Anfragen und Einladungen. + Ein vereinfachtes Element mit optionalen Tabs + Neues Layout aktivieren + Neueste Aktivität + Neueste Aktivität %1$s + Verifiziere deine aktuelle Sitzung für besonders sichere Kommunikation. + Deine aktuelle Sitzung ist für sichere Kommunikation bereit. + Details anzeigen + Für bestmögliche Sicherheit und Zuverlässigkeit verifiziere diese Sitzungen oder melde dich von ihr ab. + Für bestmögliche Sicherheit melde dich von allen Sitzungen ab, die du nicht erkennst oder nutzt. + \ No newline at end of file From 2a5a85af1f7aa00f384ebe159c00e1cd43cb576a Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 24 Sep 2022 15:26:06 +0000 Subject: [PATCH 031/136] Translated using Weblate (Hungarian) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- .../src/main/res/values-hu/strings.xml | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) 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 3068556fe4..cac0a2eb5d 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2668,4 +2668,46 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze %1$d+ napja inaktív (%2$s) Itt láthatók a meghívók és elvégzendő műveletek. - + IP cím + Utolsó tevékenység + Munkamenet neve + Alkalmazás, eszköz és aktivitás információ. + Munkamenet információk + Szűrő törlése + Nincs inaktív munkamenet. + Nincs ellenőrizetlen munkamenet. + Nincs ellenőrzött munkamenet. + + Fontold meg, hogy kijelentkezel a régi munkamenetekből (%1$d napja vagy régebben használtál) amit már nem használsz. + Fontold meg, hogy kijelentkezel a régi munkamenetekből (%1$d napja vagy régebben használtál) amit már nem használsz. + + Inaktív + Erősítse meg a munkameneteit a még biztonságosabb csevegéshez vagy jelentkezzen ki ezekből, ha nem ismeri fel vagy már nem használja őket. + Ellenőrizetlen + A legjobb biztonság érdekében jelentkezz ki minden olyan munkamenetből amit nem ismersz fel vagy régen használtál már. + Hitelesített + Szűrés + + %1$d napja inaktív + %1$d napja inaktív + + Inaktív + Nem áll készen a biztonságos üzenetküldésre + Ellenőrizetlen + Felkészülve a biztonságos üzenetküldésre + Hitelesített + Minden munkamenet + Szűrés + Utolsó aktivitás %1$s + Eszköz + Munkamenet + Jelenlegi munkamenet + A jobb biztonság vagy megbízhatóság érdekében ellenőrizze vagy jelentkezzen ki ebből a munkamenetből. + Az aktuális munkamenet készen áll a biztonságos üzenetküldésre. + Ez a munkamenet beállítva a biztonságos üzenetküldéshez. + Az aktuális munkamenet készen áll a biztonságos üzenetküldésre. + Közvetlen beszélgetés indítása csak az első üzenettel + Késleltetett közvetlen üzenetek engedélyezése + Egyszerűsített Element opcionálisan lapokkal + Új kinézet engedélyezése + \ No newline at end of file From 312111c35a3bdcdbb4c1dafdd68c7f34680b8b29 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Fri, 23 Sep 2022 20:19:45 +0000 Subject: [PATCH 032/136] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- .../src/main/res/values-pt-rBR/strings.xml | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) 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 817c7646df..23434766b6 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 @@ -473,7 +473,7 @@ Você tem certeza que você quer começar uma chamada de vídeo\? Tirar foto Tirar vídeo - Chamar + Chamada Banir usuária(o) vai removê-la(o) desta sala e preveni-la(o) de se juntar de novo. Todas as mensagens Adicionar a tela de Início @@ -2658,8 +2658,8 @@ Melhore a segurança de sua conta ao seguir estas recomendações. Recomendações de segurança - Inativa(o) por %1$d+ dia (%2$s) - Inativa(o) por %1$d+ dias (%2$s) + Inativa por %1$d+ dia (%2$s) + Inativa por %1$d+ dias (%2$s) Isto é onde suas novas requisições e convites vão estar. Nada novo. @@ -2668,4 +2668,46 @@ Colapsar filhos de %s Expandir filhos de %s Mudar Espaço - + Não-verificadas + Verificadas + Não-verificadas + Verificadas + Inativas + + Inativas por %1$d dia ou mais longo + Inativas por %1$d dias ou mais longo + + Inativas + Endereço de IP + Última atividade + Nome de sessão + Informação de aplicativo, dispositivo, e atividade. + Detalhes de sessão + Limpar Filtro + Nenhuma sessão inativa encontrada. + Nenhuma sessão não-verificada encontrada. + Nenhuma sessão verificada encontrada. + + Considere fazer signout de sessões antigas (%1$d dia ou mais) que você não usa mais. + Considere fazer signout de sessões antigas (%1$d dias ou mais) que você não usa mais. + + Verifique suas sessões para mensageria segura melhorada ou faça signout daquelas que você não reconhece ou usa mais. + Para melhor segurança, faça signout de qualquer sessão que você não reconhece ou usa mais. + Filtrar + Pronta para mensageria segura + Não pronta para mensageria segura + Todas as sessões + Filtrar + Última atividade %1$s + Dispositivo + Sessão + Sessão Atual + Verifique ou faça signout desta sessão para melhor segurança e fiabilidade. + Verifique sua sessão atual para mensageria segura melhorada. + Esta sessão está pronta para mensageria segura. + Sua sessão atual está pronta para mensageria segura. + Criar DM somente em primeira mensagem + Habilitar DMs diferidas + Um Element simplificado com abas opcionais + Habilitar novo layout + \ No newline at end of file From d86594099c2d5df1dbb6b945b0419f833dfbb694 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Sat, 24 Sep 2022 23:15:52 +0000 Subject: [PATCH 033/136] Translated using Weblate (Russian) Currently translated at 97.9% (2370 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- .../src/main/res/values-ru/strings.xml | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) 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 e0ab799a57..38dd4a831e 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -907,7 +907,7 @@ Событие удалено пользователем Событие модерируется администратором комнаты Некорректное событие, не могу отобразить - Создать новую комнату + Создать комнату Нет сети. Пожалуйста, проверьте подключение к Интернету. Изменить Изменить сеть @@ -916,7 +916,7 @@ Комнаты Личные сообщения СОЗДАТЬ - Имя + Название Публичная Каждый сможет присоединиться к этой комнате Произошла ошибка при получении информации о доверии @@ -958,8 +958,8 @@ Не можете найти нужное\? Создать комнату Отправить личное сообщение - Просмотр каталога комнат - Имя или ID (#example:matrix.org) + Каталог комнат + Название или ID (#example:matrix.org) Жест смахивания для ответа в ленте сообщений Ссылка скопирована в буфер обмена Создаем комнату… @@ -2116,7 +2116,7 @@ Сканируйте код с помощью другого устройства или переключитесь и сканируйте с помощью этого устройства Адрес пространства Файл слишком большой для загрузки. - Поиск по имени + Поиск по названию Сжатие видео %d%% Сжатие изображения… Оставить отзыв @@ -2374,11 +2374,11 @@ Опрос Создать опрос Перезапустите приложение, чтобы изменения вступили в силу. - Включить математику LaTeX + Математика LaTeX Ваша система будет автоматически отправлять журналы при возникновении ошибки невозможности расшифровки Автоматически сообщать об ошибках расшифровки. Шифрование неправильно настроено - Изменить цвет отображаемого имени + Изменить цвет имени Восстановить шифрование Обратитесь к администратору, чтобы восстановить шифрование до рабочего состояния. Шифрование настроено неправильно. @@ -2507,7 +2507,7 @@ Идёт отправка местоположения Осталось %1$s Обновлено %1$s назад - Включить функцию \"Поделиться трансляцией местоположения\" + Функция \"Поделиться трансляцией местоположения\" ${app_name} Трансляция местоположения Транслировать до %1$s Трансляция завершена @@ -2666,7 +2666,7 @@ Создать беседу или комнату Показать все сессии (V2, в разработке) Люди - Настройки оформления + Настройки вида Фильтры Недавние Избранные @@ -2675,8 +2675,8 @@ А - Я Активности Сортировать по - Обзор комнат - Начать беседу + Каталог комнат + Отправить ЛС Создать комнату Посмотреть все (%1$d) Повысьте безопасность учётной записи, следуя этим рекомендациям. @@ -2711,5 +2711,20 @@ Текущая сессия готова к безопасному обмену сообщениями. Веб-браузер Пространства — это новый способ организации комнат и людей. Создайте пространство, чтобы начать. - Новое оформление + Новый вид + Нечего отображать. + Здесь будут отображаться непрочитанные сообщения, когда таковые будут. + Присущий системе + Смена пространства + Упрощённый Element с дополнительными вкладками + Добро пожаловать в новый вид! + %s +\nвыглядит слегка пустовато. + Попробовать + Сведения о приложении, устройстве и активности. + Подтвердите текущую сессию для более безопасного обмена сообщениями. + Пока нет пространств. + Подтвердите свои сессии для более безопасного обмена сообщениями или выйдите из тех, которые более не признаёте или не используете. + Подтвердите или выйдите из незаверенных сессий. + Подтвердите или выйдите из этой сессии для лучшей безопасности и надёжности. \ No newline at end of file From e315db3c8eb910a9298cbe4a527282b413b0b648 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 23 Sep 2022 19:15:22 +0000 Subject: [PATCH 034/136] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2419 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- library/ui-strings/src/main/res/values-uk/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 41626bd156..c4f1658f6b 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -818,7 +818,7 @@ URL-адреса аватара Ваше показуване ім\'я Скасувати доступ для мене - Відкрити в переглядачі + Відкрити у браузері Перезавантажити віджет Не вдалося завантажити віджет. \n%s @@ -1196,7 +1196,7 @@ Використати файл Скористатись парольною фразою відновлення або ключем Скористатись відновлювальними парольною фразою або ключем - Використовуйте найостаннішій ${app_name} на ваших інших пристроях, ${app_name} Web, ${app_name} для комп\'ютерів, ${app_name} iOS, ${app_name} для Android, або будь-який інший, здатний до перехресного підписування, Matrix-клієнт + Використовуйте найостаннішій ${app_name} на ваших інших пристроях, ${app_name} браузері, ${app_name} комп\'ютерах, ${app_name} iOS, ${app_name} Android, або будь-який інший, здатний до перехресного підписування, Matrix-клієнт Використовуйте найостаннішій ${app_name} на ваших інших пристроях: Якщо ви не можете доступитись до чинного сеансу Використайте чинний сеанс, щоб звірити цей сеанс, таким чином надавши йому доступ до зашифрованих повідомлень. @@ -2021,7 +2021,7 @@ Не вдалося отримати доступ до безпечного сховища ${app_name} iOS \n${app_name} Android - ${app_name} для переглядача + ${app_name} для браузера \n${app_name} для ПК Не вдалося зберегти медіафайл Це не дійсний ключ відновлення @@ -2701,7 +2701,7 @@ Відкрити налаштування Усі бесіди Показати всі сеанси (V2, WIP) - Для найкращої безпеки перевірте свої сеанси та вийдіть з усіх сеансів, які ви більше не розпізнаєте або не використовуєте. + Звірте свої сеанси та вийдіть з усіх сеансів, які ви більше не розпізнаєте або не використовуєте для кращої безпеки. Інші сеанси Сеанси Відкрити список кімнат From d7ce983ef44c7bdff83a55097f2d73e13c178b10 Mon Sep 17 00:00:00 2001 From: phardyle Date: Sat, 24 Sep 2022 14:41:13 +0000 Subject: [PATCH 035/136] Translated using Weblate (Chinese (Simplified)) Currently translated at 98.8% (2392 of 2419 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/ --- .../src/main/res/values-zh-rCN/strings.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 69a2fc5eef..eba96e82c3 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 @@ -2607,4 +2607,21 @@ 空间是对房间和人进行分组的新方式。创建一个空间来开始吧。 启用新布局 IP地址 + 验证你的会话以增强消息传输的安全性,或从那些你不认识或不再使用的会话登出。 + 尚未准备好安全收发消息 + 准备好安全收发消息 + 已验证 + 全部会话 + 筛选 + 上次活跃%1$s + 设备 + 会话 + 当前会话 + 验证你的会话以增强消息传输的安全性。 + 访问你的空间(右下角)比以前更快、更容易。 + 此会话已准备好安全地收发消息。 + 你当前的会话已准备好安全地收发消息。 + 仅在首条消息创建私聊消息 + 启用延迟的私聊消息 + 简化的Element,带有可选的标签 \ No newline at end of file From 94b2026056e905cc4c76b98d9a0904c2c3514d90 Mon Sep 17 00:00:00 2001 From: Vri Date: Sat, 24 Sep 2022 00:04:39 +0000 Subject: [PATCH 036/136] Translated using Weblate (German) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/de/ --- fastlane/metadata/android/de-DE/changelogs/40104360.txt | 2 +- fastlane/metadata/android/de-DE/short_description.txt | 2 +- fastlane/metadata/android/de-DE/title.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fastlane/metadata/android/de-DE/changelogs/40104360.txt b/fastlane/metadata/android/de-DE/changelogs/40104360.txt index bf249af068..3c47fa7eb6 100644 --- a/fastlane/metadata/android/de-DE/changelogs/40104360.txt +++ b/fastlane/metadata/android/de-DE/changelogs/40104360.txt @@ -1,3 +1,3 @@ -Das neue App-Layout kann in den Labor-Einstellungen aktiviert werden. Probier es gerne aus! +Das neue App-Layout kann in den experimentellen Einstellungen aktiviert werden. Probier es gerne aus! Fehler bzgl. ausbleibender Benachrichtigungen und langwierigem inkrementellem Synchronisieren behoben. Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/de-DE/short_description.txt b/fastlane/metadata/android/de-DE/short_description.txt index d27bd3ef12..de571645ee 100644 --- a/fastlane/metadata/android/de-DE/short_description.txt +++ b/fastlane/metadata/android/de-DE/short_description.txt @@ -1 +1 @@ -Gruppen-Messenger - verschlüsselte Kommunikation, Gruppenchat und Videoanrufe +Gruppen-Messenger – verschlüsselte Kommunikation, Gruppen und Videoanrufe diff --git a/fastlane/metadata/android/de-DE/title.txt b/fastlane/metadata/android/de-DE/title.txt index 6304f37925..edee751d06 100644 --- a/fastlane/metadata/android/de-DE/title.txt +++ b/fastlane/metadata/android/de-DE/title.txt @@ -1 +1 @@ -Element - Sicherer Messenger +Element – Sicher kommunizieren From ef344236cd0bf5c4b0698615241e3b2f602a51fb Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Fri, 23 Sep 2022 20:03:26 +0000 Subject: [PATCH 037/136] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/ --- fastlane/metadata/android/pt-BR/changelogs/40104360.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40104360.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104360.txt b/fastlane/metadata/android/pt-BR/changelogs/40104360.txt new file mode 100644 index 0000000000..78a879ccb7 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40104360.txt @@ -0,0 +1,3 @@ +Novo Layout de App poder ser habilitado nas configurações de Labs. Por favor dê uma chance! +Consertar problemas sobre notificação faltando, e sinc incremental longo. +Changelog completo: https://github.com/vector-im/element-android/releases From 30628217ae0b07017b2db2863048c10835a734c4 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 23 Sep 2022 19:14:02 +0000 Subject: [PATCH 038/136] Translated using Weblate (Ukrainian) Currently translated at 100.0% (76 of 76 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/full_description.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt index c046d8a40a..330ddde4ae 100644 --- a/fastlane/metadata/android/uk/full_description.txt +++ b/fastlane/metadata/android/uk/full_description.txt @@ -5,7 +5,7 @@ Element — це і безпечний месенджер, і застосуно - Повністю зашифровані повідомлення для надання можливості безпечнішого корпоративного спілкування, навіть для віддалених працівників - Децентралізований чат на основі відкритого коду Matrix - Безпечний обмін файлами із зашифрованими даними для керування проєктами -- Відеочати з передачею голосу через IP та показом екрану іншим +- Відеочати з передачею голосу через IP та показом екрана іншим - Проста інтеграція з вашими улюбленими інструментами для онлайн-співпраці, інструментами керування проєктами, послугами VoIP та іншими застосунками обміну повідомленнями для команд Element цілковито відрізняється від інших застосунків обміну повідомленнями та спільної роботи. Він працює на Matrix, відкритій мережі для безпечного обміну повідомленнями та децентралізованого зв'язку. Це дозволяє самостійне розгортання, щоб надати користувачам якнайбільше володіння та контролю над їх даними та повідомленнями. From 79e4a435dab4cbf58b7e6c6e12275e8879dbd3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 24 Jul 2022 16:53:33 +0200 Subject: [PATCH 039/136] Add privacy setting to disable personalized learning by the keyboard --- changelog.d/6633.feature | 1 + library/ui-strings/src/main/res/values/strings.xml | 3 +++ .../app/features/home/room/detail/TimelineFragment.kt | 2 ++ .../home/room/detail/composer/ComposerEditText.kt | 9 +++++++++ .../im/vector/app/features/settings/VectorPreferences.kt | 7 +++++++ .../main/res/xml/vector_settings_security_privacy.xml | 6 ++++++ 6 files changed, 28 insertions(+) create mode 100644 changelog.d/6633.feature diff --git a/changelog.d/6633.feature b/changelog.d/6633.feature new file mode 100644 index 0000000000..b52e9d95bc --- /dev/null +++ b/changelog.d/6633.feature @@ -0,0 +1 @@ +Add privacy setting to disable personalized learning by the keyboard diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index d8f6222acf..4f1917f0df 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2578,6 +2578,9 @@ Prevent screenshots of the application Enabling this setting adds the FLAG_SECURE to all Activities. Restart the application for the change to take effect. + Incognito keyboard + Request that the keyboard should not update any personalized data such as typing history and dictionary based on what the user typed. Some keyboards may not respect this setting. + Could not save media file Set a new account password… diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index bba607eeb4..0a8ae775a9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1536,6 +1536,8 @@ class TimelineFragment : observerUserTyping() + composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + if (vectorPreferences.sendMessageWithEnter()) { // imeOptions="actionSend" only works with single line, so we remove multiline inputType composerEditText.inputType = composerEditText.inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index c751053cdf..6f09d25869 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -79,6 +79,11 @@ class ComposerEditText @JvmOverloads constructor( return ic } + /** Set whether the keyboard should disable personalized learning. */ + fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { + imeOptions = if (useIncognitoKeyboard) imeOptions or INCOGNITO_KEYBOARD_IME else imeOptions and INCOGNITO_KEYBOARD_IME.inv() + } + init { addTextChangedListener( object : SimpleTextWatcher() { @@ -116,4 +121,8 @@ class ComposerEditText @JvmOverloads constructor( } ) } + + companion object { + const val INCOGNITO_KEYBOARD_IME = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING + } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 16d3210b45..b7812b9ebb 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -87,6 +87,7 @@ class VectorPreferences @Inject constructor( const val SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY = "SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY" const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY" const val SETTINGS_PERSISTED_SPACE_BACKSTACK = "SETTINGS_PERSISTED_SPACE_BACKSTACK" + const val SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY = "SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY" const val SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT = "SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT" // const val SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY" @@ -288,6 +289,7 @@ class VectorPreferences @Inject constructor( SETTINGS_USE_RAGE_SHAKE_KEY, SETTINGS_SECURITY_USE_FLAG_SECURE, + SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY, ShortcutsHandler.SHARED_PREF_KEY, ) @@ -969,6 +971,11 @@ class VectorPreferences @Inject constructor( return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_FLAG_SECURE, false) } + /** Whether the keyboard should disable personalized learning. */ + fun useIncognitoKeyboard(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY, false) + } + /** * The user enable protecting app access with pin code. * Currently we use the pin code store to know if the pin is enabled, so this is not used diff --git a/vector/src/main/res/xml/vector_settings_security_privacy.xml b/vector/src/main/res/xml/vector_settings_security_privacy.xml index 1e8997e9c8..78e1ba42a8 100644 --- a/vector/src/main/res/xml/vector_settings_security_privacy.xml +++ b/vector/src/main/res/xml/vector_settings_security_privacy.xml @@ -141,6 +141,12 @@ android:summary="@string/settings_security_application_protection_summary" android:title="@string/settings_security_application_protection_title" /> + + Date: Sun, 25 Sep 2022 13:56:59 +0200 Subject: [PATCH 040/136] Improve summary text of Incognito Keyboard setting --- library/ui-strings/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 4f1917f0df..040510fba8 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2579,7 +2579,7 @@ Enabling this setting adds the FLAG_SECURE to all Activities. Restart the application for the change to take effect. Incognito keyboard - Request that the keyboard should not update any personalized data such as typing history and dictionary based on what the user typed. Some keyboards may not respect this setting. + "Request that the keyboard should not update any personalized data such as typing history and dictionary based on what you've typed in conversations. Notice that some keyboards may not respect this setting." Could not save media file Set a new account password… From e5cf431cc70d9c8e6e2a75748bcd64207f7ff135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 25 Sep 2022 14:42:07 +0200 Subject: [PATCH 041/136] Apply imeOptions to ComposerEditText without overriding previously set options --- .../home/room/detail/TimelineFragment.kt | 7 +------ .../room/detail/composer/ComposerEditText.kt | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 0a8ae775a9..de2f9891e1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1537,12 +1537,7 @@ class TimelineFragment : observerUserTyping() composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) - - if (vectorPreferences.sendMessageWithEnter()) { - // imeOptions="actionSend" only works with single line, so we remove multiline inputType - composerEditText.inputType = composerEditText.inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() - composerEditText.imeOptions = EditorInfo.IME_ACTION_SEND - } + composerEditText.setSendMessageWithEnter(vectorPreferences.sendMessageWithEnter()) composerEditText.setOnEditorActionListener { v, actionId, keyEvent -> val imeActionId = actionId and EditorInfo.IME_MASK_ACTION diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index 6f09d25869..911261d46f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -81,7 +81,22 @@ class ComposerEditText @JvmOverloads constructor( /** Set whether the keyboard should disable personalized learning. */ fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { - imeOptions = if (useIncognitoKeyboard) imeOptions or INCOGNITO_KEYBOARD_IME else imeOptions and INCOGNITO_KEYBOARD_IME.inv() + imeOptions = if (useIncognitoKeyboard) { + imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING + } else { + imeOptions and EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING.inv() + } + } + + /** Set whether enter should send the message or add a new line. */ + fun setSendMessageWithEnter(sendMessageWithEnter: Boolean) { + if (sendMessageWithEnter) { + inputType = inputType and EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE.inv() + imeOptions = imeOptions or EditorInfo.IME_ACTION_SEND + } else { + inputType = inputType or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE + imeOptions = imeOptions and EditorInfo.IME_ACTION_SEND.inv() + } } init { @@ -121,8 +136,4 @@ class ComposerEditText @JvmOverloads constructor( } ) } - - companion object { - const val INCOGNITO_KEYBOARD_IME = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING - } } From 079a2f53514f4270e530f980dd14058186ed8188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Be=C5=88o?= Date: Sun, 25 Sep 2022 14:56:20 +0200 Subject: [PATCH 042/136] Hide Incognito Keyboard setting on unsupported devices --- .../features/home/room/detail/TimelineFragment.kt | 4 +++- .../home/room/detail/composer/ComposerEditText.kt | 3 +++ .../VectorSettingsSecurityPrivacyFragment.kt | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index de2f9891e1..853d8918a4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1536,7 +1536,9 @@ class TimelineFragment : observerUserTyping() - composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + composerEditText.setUseIncognitoKeyboard(vectorPreferences.useIncognitoKeyboard()) + } composerEditText.setSendMessageWithEnter(vectorPreferences.sendMessageWithEnter()) composerEditText.setOnEditorActionListener { v, actionId, keyEvent -> diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt index 911261d46f..9e88882866 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/ComposerEditText.kt @@ -20,10 +20,12 @@ package im.vector.app.features.home.room.detail.composer import android.content.ClipData import android.content.Context import android.net.Uri +import android.os.Build import android.text.Editable import android.util.AttributeSet import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection +import androidx.annotation.RequiresApi import androidx.appcompat.widget.AppCompatEditText import androidx.core.view.OnReceiveContentListener import androidx.core.view.ViewCompat @@ -80,6 +82,7 @@ class ComposerEditText @JvmOverloads constructor( } /** Set whether the keyboard should disable personalized learning. */ + @RequiresApi(Build.VERSION_CODES.O) fun setUseIncognitoKeyboard(useIncognitoKeyboard: Boolean) { imeOptions = if (useIncognitoKeyboard) { imeOptions or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 5cbdf114a5..87f5af67eb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -20,6 +20,7 @@ package im.vector.app.features.settings import android.app.Activity import android.content.Intent import android.net.Uri +import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -160,6 +161,10 @@ class VectorSettingsSecurityPrivacyFragment : findPreference("SETTINGS_USER_ANALYTICS_CONSENT_KEY")!! } + private val incognitoKeyboardPref by lazy { + findPreference(VectorPreferences.SETTINGS_SECURITY_INCOGNITO_KEYBOARD_PREFERENCE_KEY)!! + } + override fun onCreateRecyclerView(inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle?): RecyclerView { return super.onCreateRecyclerView(inflater, parent, savedInstanceState).also { // Insert animation are really annoying the first time the list is shown @@ -275,6 +280,9 @@ class VectorSettingsSecurityPrivacyFragment : // Analytics setUpAnalytics() + // Incognito Keyboard + setUpIncognitoKeyboard() + // Pin code openPinCodeSettingsPref.setOnPreferenceClickListener { openPinCodePreferenceScreen() @@ -337,6 +345,10 @@ class VectorSettingsSecurityPrivacyFragment : } } + private fun setUpIncognitoKeyboard() { + incognitoKeyboardPref.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + } + // Todo this should be refactored and use same state as 4S section private fun refreshXSigningStatus() { val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys() From c70b6206d0a3394cf4a874967b83c87f31daff5d Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 26 Sep 2022 14:39:23 +0300 Subject: [PATCH 043/136] Add user agent into device info. --- .../api/session/crypto/model/DeviceInfo.kt | 10 +++- .../settings/devices/v2/DeviceFullInfo.kt | 1 + .../settings/devices/v2/DeviceUserAgent.kt | 46 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt index b144069b99..338a594011 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt @@ -52,9 +52,17 @@ data class DeviceInfo( * The last ip address. */ @Json(name = "last_seen_ip") - val lastSeenIp: String? = null + val lastSeenIp: String? = null, + + @Json(name="org.matrix.msc3852.last_seen_user_agent") + val unstableLastSeenUserAgent: String? = null, + + @Json(name="last_seen_user_agent") + val lastSeenUserAgent: String? = null, ) : DatedObject { override val date: Long get() = lastSeenTs ?: 0 + + fun getBestLastSeenUserAgent() = lastSeenUserAgent ?: unstableLastSeenUserAgent } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceFullInfo.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceFullInfo.kt index 373df53b1b..a47a9340c3 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceFullInfo.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceFullInfo.kt @@ -26,4 +26,5 @@ data class DeviceFullInfo( val roomEncryptionTrustLevel: RoomEncryptionTrustLevel, val isInactive: Boolean, val isCurrentDevice: Boolean, + val deviceUserAgent: DeviceUserAgent, ) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt new file mode 100644 index 0000000000..14b02ce073 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2 + +import im.vector.app.features.settings.devices.v2.list.DeviceType + +data class DeviceUserAgent( + /** + * One of MOBILE, WEB, DESKTOP or UNKNOWN + */ + val deviceType: DeviceType, + /** + * i.e. Google Pixel 6 + */ + val deviceModel: String?, + /** + * i.e. Android + */ + val deviceOperatingSystem: String?, + /** + * i.e. Android 11 + */ + val deviceOperatingSystemVersion: String?, + /** + * i.e. Element Nightly + */ + val clientName: String?, + /** + * i.e. 1.5.0 + */ + val clientVersion: String?, +) From dc1abb79781af776315cd7b673225ffd4f648a96 Mon Sep 17 00:00:00 2001 From: yostyle Date: Fri, 23 Sep 2022 15:46:09 +0200 Subject: [PATCH 044/136] Add Activities of android permission controller in the whitelist --- .../features/lifecycle/VectorActivityLifecycleCallbacks.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt index c884843f5c..6fc1bcf6c7 100644 --- a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt +++ b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.extensions.tryOrNull import timber.log.Timber class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager: PopupAlertManager) : Application.ActivityLifecycleCallbacks { @@ -94,9 +95,13 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager val context = activity.applicationContext val packageManager: PackageManager = context.packageManager - // Get all activities from app manifest + // Get all activities from element android and android permission controller app if (activitiesInfo.isEmpty()) { activitiesInfo = packageManager.getPackageInfo(context.packageName, PackageManager.GET_ACTIVITIES).activities + + activitiesInfo += tryOrNull { + packageManager.getPackageInfo("com.google.android.permissioncontroller", PackageManager.GET_ACTIVITIES).activities + } ?: emptyArray() } // Get all running activities on app task From bd64749b48098864d91e76aadc74ea71bff52a23 Mon Sep 17 00:00:00 2001 From: yostyle Date: Fri, 23 Sep 2022 18:03:54 +0200 Subject: [PATCH 045/136] Add changelog --- changelog.d/7224.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7224.bugfix diff --git a/changelog.d/7224.bugfix b/changelog.d/7224.bugfix new file mode 100644 index 0000000000..e48925e9e6 --- /dev/null +++ b/changelog.d/7224.bugfix @@ -0,0 +1 @@ +Fix app restarts in loop on Android 13 on the first run of the app. From 8dc71e07edef7666f27489e419c093197082d989 Mon Sep 17 00:00:00 2001 From: yostyle Date: Tue, 27 Sep 2022 00:24:10 +0200 Subject: [PATCH 046/136] Add activities from Android API 33. --- .../VectorActivityLifecycleCallbacks.kt | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt index 6fc1bcf6c7..5bdd92dcf4 100644 --- a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt +++ b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt @@ -59,6 +59,26 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager override fun onActivityStopped(activity: Activity) {} override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { + if (activitiesInfo.isEmpty()) { + val context = activity.applicationContext + val packageManager: PackageManager = context.packageManager + + // Get all activities from element android + activitiesInfo = packageManager.getPackageInfo(context.packageName, PackageManager.GET_ACTIVITIES).activities + + // Get all activities from PermissionController module + // See https://source.android.com/docs/core/architecture/modular-system/permissioncontroller#package-format + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) { + activitiesInfo += tryOrNull { + packageManager.getPackageInfo("com.google.android.permissioncontroller", PackageManager.GET_ACTIVITIES).activities + } ?: tryOrNull { + packageManager.getModuleInfo("com.google.android.permission", 1).packageName?.let { + packageManager.getPackageInfo(it, PackageManager.GET_ACTIVITIES or PackageManager.MATCH_APEX).activities + } + }.orEmpty() + } + } + // restart the app if the task contains an unknown activity coroutineScope.launch { val isTaskCorrupted = try { @@ -93,16 +113,6 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager */ private suspend fun isTaskCorrupted(activity: Activity): Boolean = withContext(Dispatchers.Default) { val context = activity.applicationContext - val packageManager: PackageManager = context.packageManager - - // Get all activities from element android and android permission controller app - if (activitiesInfo.isEmpty()) { - activitiesInfo = packageManager.getPackageInfo(context.packageName, PackageManager.GET_ACTIVITIES).activities - - activitiesInfo += tryOrNull { - packageManager.getPackageInfo("com.google.android.permissioncontroller", PackageManager.GET_ACTIVITIES).activities - } ?: emptyArray() - } // Get all running activities on app task // and compare to activities declared in manifest @@ -127,7 +137,7 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager runningTaskInfo.topActivity?.let { // Check whether the activity task affinity matches with app task affinity. // The activity is considered safe when its task affinity doesn't correspond to app task affinity. - if (packageManager.getActivityInfo(it, 0).taskAffinity == context.applicationInfo.taskAffinity) { + if (context.packageManager.getActivityInfo(it, 0).taskAffinity == context.applicationInfo.taskAffinity) { isPotentialMaliciousActivity(it) } else false } ?: false From 3e66a6538ee4e43cbe03876c22d9b0810361adf6 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 27 Sep 2022 15:45:34 +0300 Subject: [PATCH 047/136] Implement use case to parse user agent. --- .../settings/devices/v2/DeviceUserAgent.kt | 20 +++-- .../devices/v2/ParseDeviceUserAgentUseCase.kt | 90 +++++++++++++++++++ 2 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt index 14b02ce073..f307025d0b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt @@ -24,23 +24,31 @@ data class DeviceUserAgent( */ val deviceType: DeviceType, /** - * i.e. Google Pixel 6 + * i.e. Google */ - val deviceModel: String?, + val deviceManufacturer: String? = null, + /** + * i.e. Pixel 6 + */ + val deviceModel: String? = null, /** * i.e. Android */ - val deviceOperatingSystem: String?, + val deviceOperatingSystem: String? = null, /** * i.e. Android 11 */ - val deviceOperatingSystemVersion: String?, + val deviceOperatingSystemVersion: String? = null, /** * i.e. Element Nightly */ - val clientName: String?, + val clientName: String? = null, /** * i.e. 1.5.0 */ - val clientVersion: String?, + val clientVersion: String? = null, + /** + * i.e. Chrome + */ + val browser: String? = null, ) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt new file mode 100644 index 0000000000..1ea7dabbe4 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2 + +import im.vector.app.features.settings.devices.v2.list.DeviceType +import javax.inject.Inject + +class ParseDeviceUserAgentUseCase @Inject constructor() { + + fun execute(userAgent: String): DeviceUserAgent { + return when { + userAgent.contains(ANDROID_KEYWORD) -> parseAndroidUserAgent(userAgent) + userAgent.contains(IOS_KEYWORD) -> parseIosUserAgent(userAgent) + userAgent.contains(DESKTOP_KEYWORD) -> parseDesktopUserAgent(userAgent) + userAgent.contains(WEB_KEYWORD) -> parseWebUserAgent(userAgent) + else -> createUnknownUserAgent() + } + } + + private fun parseAndroidUserAgent(userAgent: String): DeviceUserAgent { + val appName = userAgent.substringBefore("/") + val appVersion = userAgent.substringAfter("/").substringBefore(" (") + val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceManufacturer = deviceInfoSegments.getOrNull(0) + val deviceModel = deviceInfoSegments.getOrNull(1) + val deviceOsInfo = deviceInfoSegments.getOrNull(2)?.takeIf { it.startsWith("Android") } + val deviceOs = deviceOsInfo?.substringBefore(" ") + val deviceOsVersion = deviceOsInfo?.substringAfter(" ") + return DeviceUserAgent(DeviceType.MOBILE, deviceManufacturer, deviceModel, deviceOs, deviceOsVersion, appName, appVersion) + } + + private fun parseIosUserAgent(userAgent: String): DeviceUserAgent { + val appName = userAgent.substringBefore("/") + val appVersion = userAgent.substringAfter("/").substringBefore(" (") + val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceManufacturer = "Apple" + val deviceModel = deviceInfoSegments.getOrNull(0) + val deviceOs = deviceInfoSegments.getOrNull(1)?.substringBefore(" ") + val deviceOsVersion = deviceInfoSegments.getOrNull(1)?.substringAfter(" ") + return DeviceUserAgent(DeviceType.MOBILE, deviceManufacturer, deviceModel, deviceOs, deviceOsVersion, appName, appVersion) + } + + private fun parseDesktopUserAgent(userAgent: String): DeviceUserAgent { + val appInfoSegments = userAgent.substringBeforeLast(" ").substringAfterLast(" ").split("/") + val appName = appInfoSegments.getOrNull(0) + val appVersion = appInfoSegments.getOrNull(1) + val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceOs = deviceInfoSegments.getOrNull(1)?.substringBeforeLast(" ") + val deviceOsVersion = deviceInfoSegments.getOrNull(1)?.substringAfterLast(" ") + return DeviceUserAgent(DeviceType.DESKTOP, null, null, deviceOs, deviceOsVersion, appName, appVersion) + } + + private fun parseWebUserAgent(userAgent: String): DeviceUserAgent { + return parseDesktopUserAgent(userAgent).copy( + deviceType = DeviceType.WEB + ) + } + + private fun createUnknownUserAgent(): DeviceUserAgent { + return DeviceUserAgent(DeviceType.UNKNOWN) + } + + companion object { + // Element dbg/1.5.0-dev (Xiaomi; Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.0) + private val ANDROID_KEYWORD = "; MatrixAndroidSdk2" + + // Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00) + private val IOS_KEYWORD = "; iOS " + + // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36 + private val DESKTOP_KEYWORD = " Electron/" + + // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 + private val WEB_KEYWORD = "Mozilla/" + } +} From 0d6cbbdb5dc4218a91e0bbdc0bfc304f784946e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 16:41:13 +0000 Subject: [PATCH 048/136] Bump dependency-check-gradle from 7.2.0 to 7.2.1 Bumps dependency-check-gradle from 7.2.0 to 7.2.1. --- updated-dependencies: - dependency-name: org.owasp:dependency-check-gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a748594a8c..93e08192c6 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ buildscript { classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5' classpath "com.likethesalad.android:stem-plugin:2.2.2" - classpath 'org.owasp:dependency-check-gradle:7.2.0' + classpath 'org.owasp:dependency-check-gradle:7.2.1' classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.10" classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0" classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3' From 5f778fff013a33cd9bda2629ea4378e9fceda39d Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 28 Sep 2022 10:09:13 +0100 Subject: [PATCH 049/136] re-enabling the jetifier, it's required by the autocomplete library - the upstream library source doesn't require the jetifier however it hasn't been released --- gradle.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ded5a43e28..2c999af35d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,8 @@ org.gradle.vfs.watch=true org.gradle.caching=true # Android Settings -android.enableJetifier=false +android.enableJetifier=true +android.jetifier.ignorelist=android-base-common,common android.useAndroidX=true #Project Settings From 04a305b40329d27af031d7a0af0f982943bc8f28 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 28 Sep 2022 14:32:20 +0300 Subject: [PATCH 050/136] Refactor user agent parsing. --- .../settings/devices/v2/DeviceUserAgent.kt | 12 ++----- .../v2/GetDeviceFullInfoListUseCase.kt | 4 ++- .../devices/v2/ParseDeviceUserAgentUseCase.kt | 33 +++++++++++-------- .../v2/overview/GetDeviceFullInfoUseCase.kt | 5 +++ .../devices/v2/DevicesViewModelTest.kt | 8 +++-- .../v2/GetDeviceFullInfoListUseCaseTest.kt | 12 +++++-- .../v2/filter/FilterDevicesUseCaseTest.kt | 14 +++++--- .../overview/GetDeviceFullInfoUseCaseTest.kt | 8 ++++- 8 files changed, 61 insertions(+), 35 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt index f307025d0b..cf201fafa4 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt @@ -24,21 +24,13 @@ data class DeviceUserAgent( */ val deviceType: DeviceType, /** - * i.e. Google - */ - val deviceManufacturer: String? = null, - /** - * i.e. Pixel 6 + * i.e. Google Pixel 6 */ val deviceModel: String? = null, - /** - * i.e. Android - */ - val deviceOperatingSystem: String? = null, /** * i.e. Android 11 */ - val deviceOperatingSystemVersion: String? = null, + val deviceOperatingSystem: String? = null, /** * i.e. Element Nightly */ diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt index b2341e23f7..e4cdbb0a87 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt @@ -38,6 +38,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor( private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase, private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase, private val filterDevicesUseCase: FilterDevicesUseCase, + private val parseDeviceUserAgentUseCase: ParseDeviceUserAgentUseCase, ) { fun execute(filterType: DeviceManagerFilterType, excludeCurrentDevice: Boolean = false): Flow> { @@ -72,7 +73,8 @@ class GetDeviceFullInfoListUseCase @Inject constructor( val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoDeviceInfo?.deviceId - DeviceFullInfo(deviceInfo, cryptoDeviceInfo, roomEncryptionTrustLevel, isInactive, isCurrentDevice) + val deviceUserAgent = parseDeviceUserAgentUseCase.execute(deviceInfo.lastSeenUserAgent) + DeviceFullInfo(deviceInfo, cryptoDeviceInfo, roomEncryptionTrustLevel, isInactive, isCurrentDevice, deviceUserAgent) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt index 1ea7dabbe4..fe02aa6400 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt @@ -21,7 +21,9 @@ import javax.inject.Inject class ParseDeviceUserAgentUseCase @Inject constructor() { - fun execute(userAgent: String): DeviceUserAgent { + fun execute(userAgent: String?): DeviceUserAgent { + if (userAgent == null) return createUnknownUserAgent() + return when { userAgent.contains(ANDROID_KEYWORD) -> parseAndroidUserAgent(userAgent) userAgent.contains(IOS_KEYWORD) -> parseIosUserAgent(userAgent) @@ -35,23 +37,26 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { val appName = userAgent.substringBefore("/") val appVersion = userAgent.substringAfter("/").substringBefore(" (") val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") - val deviceManufacturer = deviceInfoSegments.getOrNull(0) - val deviceModel = deviceInfoSegments.getOrNull(1) - val deviceOsInfo = deviceInfoSegments.getOrNull(2)?.takeIf { it.startsWith("Android") } - val deviceOs = deviceOsInfo?.substringBefore(" ") - val deviceOsVersion = deviceOsInfo?.substringAfter(" ") - return DeviceUserAgent(DeviceType.MOBILE, deviceManufacturer, deviceModel, deviceOs, deviceOsVersion, appName, appVersion) + val deviceModel: String? + val deviceOperatingSystem: String? + if (deviceInfoSegments.firstOrNull() == "Linux") { + val deviceOperatingSystemIndex = deviceInfoSegments.indexOfFirst { it.startsWith("Android") } + deviceOperatingSystem = deviceInfoSegments.getOrNull(deviceOperatingSystemIndex) + deviceModel = deviceInfoSegments.getOrNull(deviceOperatingSystemIndex + 1) + } else { + deviceModel = deviceInfoSegments.getOrNull(0) + deviceOperatingSystem = deviceInfoSegments.getOrNull(1) + } + return DeviceUserAgent(DeviceType.MOBILE, deviceModel, deviceOperatingSystem, appName, appVersion) } private fun parseIosUserAgent(userAgent: String): DeviceUserAgent { val appName = userAgent.substringBefore("/") val appVersion = userAgent.substringAfter("/").substringBefore(" (") val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") - val deviceManufacturer = "Apple" val deviceModel = deviceInfoSegments.getOrNull(0) - val deviceOs = deviceInfoSegments.getOrNull(1)?.substringBefore(" ") - val deviceOsVersion = deviceInfoSegments.getOrNull(1)?.substringAfter(" ") - return DeviceUserAgent(DeviceType.MOBILE, deviceManufacturer, deviceModel, deviceOs, deviceOsVersion, appName, appVersion) + val deviceOperatingSystem = deviceInfoSegments.getOrNull(1) + return DeviceUserAgent(DeviceType.MOBILE, deviceModel, deviceOperatingSystem, appName, appVersion) } private fun parseDesktopUserAgent(userAgent: String): DeviceUserAgent { @@ -59,9 +64,8 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { val appName = appInfoSegments.getOrNull(0) val appVersion = appInfoSegments.getOrNull(1) val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") - val deviceOs = deviceInfoSegments.getOrNull(1)?.substringBeforeLast(" ") - val deviceOsVersion = deviceInfoSegments.getOrNull(1)?.substringAfterLast(" ") - return DeviceUserAgent(DeviceType.DESKTOP, null, null, deviceOs, deviceOsVersion, appName, appVersion) + val deviceOperatingSystem = deviceInfoSegments.getOrNull(1) + return DeviceUserAgent(DeviceType.DESKTOP, null, deviceOperatingSystem, appName, appVersion) } private fun parseWebUserAgent(userAgent: String): DeviceUserAgent { @@ -76,6 +80,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { companion object { // Element dbg/1.5.0-dev (Xiaomi; Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.0) + // Legacy : Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSdk2 1.0) private val ANDROID_KEYWORD = "; MatrixAndroidSdk2" // Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index 121973a134..cfaa6aed85 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt @@ -19,12 +19,14 @@ package im.vector.app.features.settings.devices.v2.overview import androidx.lifecycle.asFlow import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.settings.devices.v2.DeviceFullInfo +import im.vector.app.features.settings.devices.v2.ParseDeviceUserAgentUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.emptyFlow +import okhttp3.internal.userAgent import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.flow.unwrap import javax.inject.Inject @@ -34,6 +36,7 @@ class GetDeviceFullInfoUseCase @Inject constructor( private val getCurrentSessionCrossSigningInfoUseCase: GetCurrentSessionCrossSigningInfoUseCase, private val getEncryptionTrustLevelForDeviceUseCase: GetEncryptionTrustLevelForDeviceUseCase, private val checkIfSessionIsInactiveUseCase: CheckIfSessionIsInactiveUseCase, + private val parseDeviceUserAgentUseCase: ParseDeviceUserAgentUseCase, ) { fun execute(deviceId: String): Flow { @@ -49,12 +52,14 @@ class GetDeviceFullInfoUseCase @Inject constructor( val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo) val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs ?: 0) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoInfo.deviceId + val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.lastSeenUserAgent) DeviceFullInfo( deviceInfo = info, cryptoDeviceInfo = cryptoInfo, roomEncryptionTrustLevel = roomEncryptionTrustLevel, isInactive = isInactive, isCurrentDevice = isCurrentDevice, + deviceUserAgent = deviceUserAgent, ) } else { null diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt index 44940dd2c3..e5a3962c6c 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt @@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2 import android.os.SystemClock import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MvRxTestRule +import im.vector.app.features.settings.devices.v2.list.DeviceType import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase @@ -36,6 +37,7 @@ import io.mockk.runs import io.mockk.unmockkAll import io.mockk.verify import kotlinx.coroutines.flow.flowOf +import okhttp3.internal.userAgent import org.junit.After import org.junit.Before import org.junit.Rule @@ -242,14 +244,16 @@ class DevicesViewModelTest { cryptoDeviceInfo = verifiedCryptoDeviceInfo, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, isInactive = false, - isCurrentDevice = true + isCurrentDevice = true, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) val deviceFullInfo2 = DeviceFullInfo( deviceInfo = mockk(), cryptoDeviceInfo = unverifiedCryptoDeviceInfo, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning, isInactive = true, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) val deviceFullInfoList = listOf(deviceFullInfo1, deviceFullInfo2) val deviceFullInfoListFlow = flowOf(deviceFullInfoList) diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt index 767819fd24..0537e4f652 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt @@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2 import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType import im.vector.app.features.settings.devices.v2.filter.FilterDevicesUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.list.DeviceType import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase @@ -53,6 +54,7 @@ class GetDeviceFullInfoListUseCaseTest { private val getEncryptionTrustLevelForDeviceUseCase = mockk() private val getCurrentSessionCrossSigningInfoUseCase = mockk() private val filterDevicesUseCase = mockk() + private val parseDeviceUserAgentUseCase = mockk() private val getDeviceFullInfoListUseCase = GetDeviceFullInfoListUseCase( activeSessionHolder = fakeActiveSessionHolder.instance, @@ -60,6 +62,7 @@ class GetDeviceFullInfoListUseCaseTest { getEncryptionTrustLevelForDeviceUseCase = getEncryptionTrustLevelForDeviceUseCase, getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase, filterDevicesUseCase = filterDevicesUseCase, + parseDeviceUserAgentUseCase = parseDeviceUserAgentUseCase, ) @Before @@ -110,21 +113,24 @@ class GetDeviceFullInfoListUseCaseTest { cryptoDeviceInfo = cryptoDeviceInfo1, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, isInactive = true, - isCurrentDevice = true + isCurrentDevice = true, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) val expectedResult2 = DeviceFullInfo( deviceInfo = deviceInfo2, cryptoDeviceInfo = cryptoDeviceInfo2, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, isInactive = false, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) val expectedResult3 = DeviceFullInfo( deviceInfo = deviceInfo3, cryptoDeviceInfo = cryptoDeviceInfo3, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning, isInactive = false, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) val expectedResult = listOf(expectedResult3, expectedResult2, expectedResult1) every { filterDevicesUseCase.execute(any(), any()) } returns expectedResult diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt index 2bb5168190..88828419f4 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt @@ -17,6 +17,8 @@ package im.vector.app.features.settings.devices.v2.filter import im.vector.app.features.settings.devices.v2.DeviceFullInfo +import im.vector.app.features.settings.devices.v2.DeviceUserAgent +import im.vector.app.features.settings.devices.v2.list.DeviceType import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldContainAll import org.junit.Test @@ -34,7 +36,8 @@ private val activeVerifiedDevice = DeviceFullInfo( ), roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, isInactive = false, - isCurrentDevice = true + isCurrentDevice = true, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) private val inactiveVerifiedDevice = DeviceFullInfo( deviceInfo = DeviceInfo(deviceId = "INACTIVE_VERIFIED_DEVICE"), @@ -45,7 +48,8 @@ private val inactiveVerifiedDevice = DeviceFullInfo( ), roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, isInactive = true, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) private val activeUnverifiedDevice = DeviceFullInfo( deviceInfo = DeviceInfo(deviceId = "ACTIVE_UNVERIFIED_DEVICE"), @@ -56,7 +60,8 @@ private val activeUnverifiedDevice = DeviceFullInfo( ), roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning, isInactive = false, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) private val inactiveUnverifiedDevice = DeviceFullInfo( deviceInfo = DeviceInfo(deviceId = "INACTIVE_UNVERIFIED_DEVICE"), @@ -67,7 +72,8 @@ private val inactiveUnverifiedDevice = DeviceFullInfo( ), roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning, isInactive = true, - isCurrentDevice = false + isCurrentDevice = false, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) private val devices = listOf( diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt index 04cd5fc492..392c737152 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt @@ -19,7 +19,10 @@ package im.vector.app.features.settings.devices.v2.overview import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow import im.vector.app.features.settings.devices.v2.DeviceFullInfo +import im.vector.app.features.settings.devices.v2.DeviceUserAgent +import im.vector.app.features.settings.devices.v2.ParseDeviceUserAgentUseCase import im.vector.app.features.settings.devices.v2.list.CheckIfSessionIsInactiveUseCase +import im.vector.app.features.settings.devices.v2.list.DeviceType import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrustLevelForDeviceUseCase @@ -53,12 +56,14 @@ class GetDeviceFullInfoUseCaseTest { private val getEncryptionTrustLevelForDeviceUseCase = mockk() private val checkIfSessionIsInactiveUseCase = mockk() private val fakeFlowLiveDataConversions = FakeFlowLiveDataConversions() + private val parseDeviceUserAgentUseCase = mockk() private val getDeviceFullInfoUseCase = GetDeviceFullInfoUseCase( activeSessionHolder = fakeActiveSessionHolder.instance, getCurrentSessionCrossSigningInfoUseCase = getCurrentSessionCrossSigningInfoUseCase, getEncryptionTrustLevelForDeviceUseCase = getEncryptionTrustLevelForDeviceUseCase, checkIfSessionIsInactiveUseCase = checkIfSessionIsInactiveUseCase, + parseDeviceUserAgentUseCase = parseDeviceUserAgentUseCase, ) @Before @@ -97,7 +102,8 @@ class GetDeviceFullInfoUseCaseTest { cryptoDeviceInfo = cryptoDeviceInfo, roomEncryptionTrustLevel = trustLevel, isInactive = isInactive, - isCurrentDevice = isCurrentDevice + isCurrentDevice = isCurrentDevice, + deviceUserAgent = DeviceUserAgent(DeviceType.MOBILE) ) verify { fakeActiveSessionHolder.instance.getSafeActiveSession() } verify { getCurrentSessionCrossSigningInfoUseCase.execute() } From 2bcf0c307d5cc0a0f291e4372df8a5a6256dcea0 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 28 Sep 2022 14:59:56 +0300 Subject: [PATCH 051/136] Add unit test for Android user agents. --- .../v2/ParseDeviceUserAgentUseCaseTest.kt | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt new file mode 100644 index 0000000000..65e80a9b28 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2 + +import im.vector.app.features.settings.devices.v2.list.DeviceType +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test + +private val A_USER_AGENT_LIST_FOR_ANDROID = listOf( + // New User Agent Implementation + "Element dbg/1.5.0-dev (Xiaomi Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.2)", + "Element/1.5.0 (Samsung SM-G960F; Android 6.0.1; RKQ1.200826.002; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", + "Element/1.5.0 (Google Nexus 5; Android 7.0; RKQ1.200826.002 test test; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", + // Legacy User Agent Implementation + "Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSdk2 1.0)", + "Element/1.0.0 (Linux; Android 7.0; SM-G610M Build/NRD90M; Flavour GPlay; MatrixAndroidSdk2 1.0)", +) +private val AN_EXPECTED_RESULT_LIST_FOR_ANDROID = listOf( + DeviceUserAgent(DeviceType.MOBILE, "Xiaomi Mi 9T", "Android 11", "Element dbg", "1.5.0-dev"), + DeviceUserAgent(DeviceType.MOBILE, "Samsung SM-G960F", "Android 6.0.1", "Element", "1.5.0"), + DeviceUserAgent(DeviceType.MOBILE, "Google Nexus 5", "Android 7.0", "Element", "1.5.0"), + DeviceUserAgent(DeviceType.MOBILE, "SM-A510F Build/MMB29", "Android 6.0.1", "Element", "1.0.0"), + DeviceUserAgent(DeviceType.MOBILE, "SM-G610M Build/NRD90M", "Android 7.0", "Element", "1.0.0"), +) + +class ParseDeviceUserAgentUseCaseTest { + + private val parseDeviceUserAgentUseCase = ParseDeviceUserAgentUseCase() + + @Test + fun `given an Android user agent then it should be parsed as expected`() { + A_USER_AGENT_LIST_FOR_ANDROID.forEachIndexed { index, userAgent -> + parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_ANDROID[index] + } + } +} From 41643ffb538ebea729092bdfae9469d2c81658b5 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 28 Sep 2022 15:00:16 +0300 Subject: [PATCH 052/136] Add unit test for iOS user agents. --- .../v2/ParseDeviceUserAgentUseCaseTest.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt index 65e80a9b28..1e73417ba2 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -37,6 +37,15 @@ private val AN_EXPECTED_RESULT_LIST_FOR_ANDROID = listOf( DeviceUserAgent(DeviceType.MOBILE, "SM-G610M Build/NRD90M", "Android 7.0", "Element", "1.0.0"), ) +private val A_USER_AGENT_LIST_FOR_IOS = listOf( + "Element/1.8.21 (iPhone; iOS 15.2; Scale/3.00)", + "Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00)", +) +private val AN_EXPECTED_RESULT_LIST_FOR_IOS = listOf( + DeviceUserAgent(DeviceType.MOBILE, "iPhone", "iOS 15.2", "Element", "1.8.21"), + DeviceUserAgent(DeviceType.MOBILE, "iPhone XS Max", "iOS 15.2", "Element", "1.8.21"), +) + class ParseDeviceUserAgentUseCaseTest { private val parseDeviceUserAgentUseCase = ParseDeviceUserAgentUseCase() @@ -47,4 +56,11 @@ class ParseDeviceUserAgentUseCaseTest { parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_ANDROID[index] } } + + @Test + fun `given an iOS user agent then it should be parsed as expected`() { + A_USER_AGENT_LIST_FOR_IOS.forEachIndexed { index, userAgent -> + parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_IOS[index] + } + } } From 5666383134b9a85d482d8459c73d8dcc9110ec8d Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 28 Sep 2022 18:19:25 +0300 Subject: [PATCH 053/136] Add unit test for desktop and web user agents. --- .../api/session/crypto/model/DeviceInfo.kt | 4 +- .../devices/v2/ParseDeviceUserAgentUseCase.kt | 57 +++++++++++++++++-- .../v2/overview/GetDeviceFullInfoUseCase.kt | 1 - .../devices/v2/DevicesViewModelTest.kt | 1 - .../v2/ParseDeviceUserAgentUseCaseTest.kt | 38 +++++++++++++ 5 files changed, 91 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt index 338a594011..500d016002 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt @@ -54,10 +54,10 @@ data class DeviceInfo( @Json(name = "last_seen_ip") val lastSeenIp: String? = null, - @Json(name="org.matrix.msc3852.last_seen_user_agent") + @Json(name = "org.matrix.msc3852.last_seen_user_agent") val unstableLastSeenUserAgent: String? = null, - @Json(name="last_seen_user_agent") + @Json(name = "last_seen_user_agent") val lastSeenUserAgent: String? = null, ) : DatedObject { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt index fe02aa6400..eb1daaea0e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt @@ -17,6 +17,7 @@ package im.vector.app.features.settings.devices.v2 import im.vector.app.features.settings.devices.v2.list.DeviceType +import org.matrix.android.sdk.api.extensions.orFalse import javax.inject.Inject class ParseDeviceUserAgentUseCase @Inject constructor() { @@ -60,12 +61,29 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { } private fun parseDesktopUserAgent(userAgent: String): DeviceUserAgent { - val appInfoSegments = userAgent.substringBeforeLast(" ").substringAfterLast(" ").split("/") - val appName = appInfoSegments.getOrNull(0) - val appVersion = appInfoSegments.getOrNull(1) - val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") - val deviceOperatingSystem = deviceInfoSegments.getOrNull(1) - return DeviceUserAgent(DeviceType.DESKTOP, null, deviceOperatingSystem, appName, appVersion) + val browserSegments = userAgent.split(" ") + val browserName = when { + isFirefox(browserSegments) -> { + "Firefox" + } + isMobile(browserSegments) -> { + getMobileBrowserName(browserSegments) + } + isSafari(browserSegments) -> { + "Safari" + } + else -> { + getRegularBrowserName(browserSegments) + } + } + + val deviceOperatingSystemSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceOperatingSystem = if (deviceOperatingSystemSegments.getOrNull(1)?.startsWith("Android").orFalse()) { + deviceOperatingSystemSegments.getOrNull(1) + } else { + deviceOperatingSystemSegments.getOrNull(0) + } + return DeviceUserAgent(DeviceType.DESKTOP, browserName, deviceOperatingSystem, null, null) } private fun parseWebUserAgent(userAgent: String): DeviceUserAgent { @@ -78,6 +96,33 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { return DeviceUserAgent(DeviceType.UNKNOWN) } + private fun isFirefox(browserSegments: List): Boolean { + return browserSegments.lastOrNull()?.startsWith("Firefox").orFalse() + } + + private fun isSafari(browserSegments: List): Boolean { + return browserSegments.lastOrNull()?.startsWith("Safari").orFalse() && + browserSegments.getOrNull(browserSegments.size - 2)?.startsWith("Version").orFalse() + } + + private fun isMobile(browserSegments: List): Boolean { + return browserSegments.lastOrNull()?.startsWith("Safari").orFalse() && + browserSegments.getOrNull(browserSegments.size - 2) == "Mobile" + } + + private fun getMobileBrowserName(browserSegments: List): String? { + val possibleBrowserName = browserSegments.getOrNull(browserSegments.size - 3)?.split("/")?.firstOrNull() + return if (possibleBrowserName == "Version") { + "Safari" + } else { + possibleBrowserName + } + } + + private fun getRegularBrowserName(browserSegments: List): String? { + return browserSegments.getOrNull(browserSegments.size - 2)?.split("/")?.firstOrNull() + } + companion object { // Element dbg/1.5.0-dev (Xiaomi; Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.0) // Legacy : Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSdk2 1.0) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index cfaa6aed85..fd612308fc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt @@ -26,7 +26,6 @@ import im.vector.app.features.settings.devices.v2.verification.GetEncryptionTrus import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.emptyFlow -import okhttp3.internal.userAgent import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.flow.unwrap import javax.inject.Inject diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt index e5a3962c6c..3b011ae9bb 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/DevicesViewModelTest.kt @@ -37,7 +37,6 @@ import io.mockk.runs import io.mockk.unmockkAll import io.mockk.verify import kotlinx.coroutines.flow.flowOf -import okhttp3.internal.userAgent import org.junit.After import org.junit.Before import org.junit.Rule diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt index 1e73417ba2..8eea1f7136 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -46,6 +46,30 @@ private val AN_EXPECTED_RESULT_LIST_FOR_IOS = listOf( DeviceUserAgent(DeviceType.MOBILE, "iPhone XS Max", "iOS 15.2", "Element", "1.8.21"), ) +private val A_USER_AGENT_LIST_FOR_DESKTOP = listOf( + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36", +) +private val AN_EXPECTED_RESULT_LIST_FOR_DESKTOP = listOf( + DeviceUserAgent(DeviceType.DESKTOP, "Electron", "Macintosh", null, null), + DeviceUserAgent(DeviceType.DESKTOP, "Electron", "Windows NT 10.0", null, null), +) + +private val A_USER_AGENT_LIST_FOR_WEB = listOf( + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.18", + "Mozilla/5.0 (Linux; Android 9; SM-G973U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + ) +private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf( + DeviceUserAgent(DeviceType.WEB, "Chrome", "Macintosh", null, null), + DeviceUserAgent(DeviceType.WEB, "Chrome", "Windows NT 10.0", null, null), + DeviceUserAgent(DeviceType.WEB, "Firefox", "Macintosh", null, null), + DeviceUserAgent(DeviceType.WEB, "Safari", "Macintosh", null, null), + DeviceUserAgent(DeviceType.WEB, "Chrome", "Android 9", null, null), +) + class ParseDeviceUserAgentUseCaseTest { private val parseDeviceUserAgentUseCase = ParseDeviceUserAgentUseCase() @@ -63,4 +87,18 @@ class ParseDeviceUserAgentUseCaseTest { parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_IOS[index] } } + + @Test + fun `given a Desktop user agent then it should be parsed as expected`() { + A_USER_AGENT_LIST_FOR_DESKTOP.forEachIndexed { index, userAgent -> + parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_DESKTOP[index] + } + } + + @Test + fun `given a Web user agent then it should be parsed as expected`() { + A_USER_AGENT_LIST_FOR_WEB.forEachIndexed { index, userAgent -> + parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_WEB[index] + } + } } From 7a36b10d4048f0afe6160dbd01c698a6a137c05f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 28 Sep 2022 18:22:24 +0300 Subject: [PATCH 054/136] Add changelog. --- changelog.d/7247.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7247.wip diff --git a/changelog.d/7247.wip b/changelog.d/7247.wip new file mode 100644 index 0000000000..8f2a447742 --- /dev/null +++ b/changelog.d/7247.wip @@ -0,0 +1 @@ +[Device Manager] Parse user agents From f4674b17d6504b24816d0b39c305e81fe2f2f1a2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 29 Sep 2022 09:44:46 +0200 Subject: [PATCH 055/136] Fix compilation warning. The Jitsi library does not include these permissions anymore. --- vector/src/main/AndroidManifest.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index b16e4505a6..dbc6458713 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -35,14 +35,6 @@ - - - - From c16b5d674c9b2fb705d0f38f21d6d67512d5cbb8 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 29 Sep 2022 11:36:38 +0300 Subject: [PATCH 056/136] Add more user agent support. --- .../devices/v2/ParseDeviceUserAgentUseCase.kt | 13 ++++++++++--- .../v2/ParseDeviceUserAgentUseCaseTest.kt | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt index eb1daaea0e..f6d12d7b4b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt @@ -37,7 +37,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { private fun parseAndroidUserAgent(userAgent: String): DeviceUserAgent { val appName = userAgent.substringBefore("/") val appVersion = userAgent.substringAfter("/").substringBefore(" (") - val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceInfoSegments = userAgent.substringAfter("(").substringBeforeLast(")").split("; ") val deviceModel: String? val deviceOperatingSystem: String? if (deviceInfoSegments.firstOrNull() == "Linux") { @@ -54,7 +54,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { private fun parseIosUserAgent(userAgent: String): DeviceUserAgent { val appName = userAgent.substringBefore("/") val appVersion = userAgent.substringAfter("/").substringBefore(" (") - val deviceInfoSegments = userAgent.substringAfter("(").substringBefore(")").split("; ") + val deviceInfoSegments = userAgent.substringAfter("(").substringBeforeLast(")").split("; ") val deviceModel = deviceInfoSegments.getOrNull(0) val deviceOperatingSystem = deviceInfoSegments.getOrNull(1) return DeviceUserAgent(DeviceType.MOBILE, deviceModel, deviceOperatingSystem, appName, appVersion) @@ -66,6 +66,9 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { isFirefox(browserSegments) -> { "Firefox" } + isEdge(browserSegments) -> { + "Edge" + } isMobile(browserSegments) -> { getMobileBrowserName(browserSegments) } @@ -100,6 +103,10 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { return browserSegments.lastOrNull()?.startsWith("Firefox").orFalse() } + private fun isEdge(browserSegments: List): Boolean { + return browserSegments.lastOrNull()?.startsWith("Edge").orFalse() + } + private fun isSafari(browserSegments: List): Boolean { return browserSegments.lastOrNull()?.startsWith("Safari").orFalse() && browserSegments.getOrNull(browserSegments.size - 2)?.startsWith("Version").orFalse() @@ -107,7 +114,7 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { private fun isMobile(browserSegments: List): Boolean { return browserSegments.lastOrNull()?.startsWith("Safari").orFalse() && - browserSegments.getOrNull(browserSegments.size - 2) == "Mobile" + browserSegments.getOrNull(browserSegments.size - 2)?.startsWith("Mobile").orFalse() } private fun getMobileBrowserName(browserSegments: List): String? { diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt index 8eea1f7136..afd3000af2 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -25,6 +25,8 @@ private val A_USER_AGENT_LIST_FOR_ANDROID = listOf( "Element dbg/1.5.0-dev (Xiaomi Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.2)", "Element/1.5.0 (Samsung SM-G960F; Android 6.0.1; RKQ1.200826.002; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", "Element/1.5.0 (Google Nexus 5; Android 7.0; RKQ1.200826.002 test test; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", + "Element/1.5.0 (Google (Nexus) 5; Android 7.0; RKQ1.200826.002 test test; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", + "Element/1.5.0 (Google (Nexus) (5); Android 7.0; RKQ1.200826.002 test test; Flavour FDroid; MatrixAndroidSdk2 1.5.2)", // Legacy User Agent Implementation "Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSdk2 1.0)", "Element/1.0.0 (Linux; Android 7.0; SM-G610M Build/NRD90M; Flavour GPlay; MatrixAndroidSdk2 1.0)", @@ -33,6 +35,8 @@ private val AN_EXPECTED_RESULT_LIST_FOR_ANDROID = listOf( DeviceUserAgent(DeviceType.MOBILE, "Xiaomi Mi 9T", "Android 11", "Element dbg", "1.5.0-dev"), DeviceUserAgent(DeviceType.MOBILE, "Samsung SM-G960F", "Android 6.0.1", "Element", "1.5.0"), DeviceUserAgent(DeviceType.MOBILE, "Google Nexus 5", "Android 7.0", "Element", "1.5.0"), + DeviceUserAgent(DeviceType.MOBILE, "Google (Nexus) 5", "Android 7.0", "Element", "1.5.0"), + DeviceUserAgent(DeviceType.MOBILE, "Google (Nexus) (5)", "Android 7.0", "Element", "1.5.0"), DeviceUserAgent(DeviceType.MOBILE, "SM-A510F Build/MMB29", "Android 6.0.1", "Element", "1.0.0"), DeviceUserAgent(DeviceType.MOBILE, "SM-G610M Build/NRD90M", "Android 7.0", "Element", "1.0.0"), ) @@ -40,10 +44,14 @@ private val AN_EXPECTED_RESULT_LIST_FOR_ANDROID = listOf( private val A_USER_AGENT_LIST_FOR_IOS = listOf( "Element/1.8.21 (iPhone; iOS 15.2; Scale/3.00)", "Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00)", + "Element/1.8.21 (iPad Pro (11-inch); iOS 15.2; Scale/3.00)", + "Element/1.8.21 (iPad Pro (12.9-inch) (3rd generation); iOS 15.2; Scale/3.00)", ) private val AN_EXPECTED_RESULT_LIST_FOR_IOS = listOf( DeviceUserAgent(DeviceType.MOBILE, "iPhone", "iOS 15.2", "Element", "1.8.21"), DeviceUserAgent(DeviceType.MOBILE, "iPhone XS Max", "iOS 15.2", "Element", "1.8.21"), + DeviceUserAgent(DeviceType.MOBILE, "iPad Pro (11-inch)", "iOS 15.2", "Element", "1.8.21"), + DeviceUserAgent(DeviceType.MOBILE, "iPad Pro (12.9-inch) (3rd generation)", "iOS 15.2", "Element", "1.8.21"), ) private val A_USER_AGENT_LIST_FOR_DESKTOP = listOf( @@ -61,6 +69,10 @@ private val A_USER_AGENT_LIST_FOR_WEB = listOf( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.18", "Mozilla/5.0 (Linux; Android 9; SM-G973U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H321 Safari/600.1.4", + "Mozilla/5.0 (iPhone; CPU iPhone OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H321 Safari/600.1.4", + "Mozilla/5.0 (Windows NT 6.0; rv:40.0) Gecko/20100101 Firefox/40.0", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246", ) private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf( DeviceUserAgent(DeviceType.WEB, "Chrome", "Macintosh", null, null), @@ -68,6 +80,10 @@ private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf( DeviceUserAgent(DeviceType.WEB, "Firefox", "Macintosh", null, null), DeviceUserAgent(DeviceType.WEB, "Safari", "Macintosh", null, null), DeviceUserAgent(DeviceType.WEB, "Chrome", "Android 9", null, null), + DeviceUserAgent(DeviceType.WEB, "Safari", "iPad", null, null), + DeviceUserAgent(DeviceType.WEB, "Safari", "iPhone", null, null), + DeviceUserAgent(DeviceType.WEB, "Firefox", "Windows NT 6.0", null, null), + DeviceUserAgent(DeviceType.WEB, "Edge", "Windows NT 10.0", null, null), ) class ParseDeviceUserAgentUseCaseTest { From 4c173a79aeacfc82dfff215dd80f709aeae78cb4 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 29 Sep 2022 11:40:15 +0300 Subject: [PATCH 057/136] Lint fixes. --- .../features/settings/devices/v2/DeviceUserAgent.kt | 12 ++++++------ .../devices/v2/ParseDeviceUserAgentUseCase.kt | 11 ++++++----- .../devices/v2/ParseDeviceUserAgentUseCaseTest.kt | 6 ++++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt index cf201fafa4..28fa8af41c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DeviceUserAgent.kt @@ -20,27 +20,27 @@ import im.vector.app.features.settings.devices.v2.list.DeviceType data class DeviceUserAgent( /** - * One of MOBILE, WEB, DESKTOP or UNKNOWN + * One of MOBILE, WEB, DESKTOP or UNKNOWN. */ val deviceType: DeviceType, /** - * i.e. Google Pixel 6 + * i.e. Google Pixel 6. */ val deviceModel: String? = null, /** - * i.e. Android 11 + * i.e. Android 11. */ val deviceOperatingSystem: String? = null, /** - * i.e. Element Nightly + * i.e. Element Nightly. */ val clientName: String? = null, /** - * i.e. 1.5.0 + * i.e. 1.5.0. */ val clientVersion: String? = null, /** - * i.e. Chrome + * i.e. Chrome. */ val browser: String? = null, ) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt index f6d12d7b4b..48ea1b2ad0 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCase.kt @@ -133,15 +133,16 @@ class ParseDeviceUserAgentUseCase @Inject constructor() { companion object { // Element dbg/1.5.0-dev (Xiaomi; Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.0) // Legacy : Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSdk2 1.0) - private val ANDROID_KEYWORD = "; MatrixAndroidSdk2" + private const val ANDROID_KEYWORD = "; MatrixAndroidSdk2" // Element/1.8.21 (iPhone XS Max; iOS 15.2; Scale/3.00) - private val IOS_KEYWORD = "; iOS " + private const val IOS_KEYWORD = "; iOS " - // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36 - private val DESKTOP_KEYWORD = " Electron/" + // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 + // Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36 + private const val DESKTOP_KEYWORD = " Electron/" // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 - private val WEB_KEYWORD = "Mozilla/" + private const val WEB_KEYWORD = "Mozilla/" } } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt index afd3000af2..0cc59f1d14 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -51,11 +51,13 @@ private val AN_EXPECTED_RESULT_LIST_FOR_IOS = listOf( DeviceUserAgent(DeviceType.MOBILE, "iPhone", "iOS 15.2", "Element", "1.8.21"), DeviceUserAgent(DeviceType.MOBILE, "iPhone XS Max", "iOS 15.2", "Element", "1.8.21"), DeviceUserAgent(DeviceType.MOBILE, "iPad Pro (11-inch)", "iOS 15.2", "Element", "1.8.21"), - DeviceUserAgent(DeviceType.MOBILE, "iPad Pro (12.9-inch) (3rd generation)", "iOS 15.2", "Element", "1.8.21"), + DeviceUserAgent(DeviceType.MOBILE, "iPad Pro (12.9-inch) (3rd generation)", "iOS 15.2", + "Element", "1.8.21"), ) private val A_USER_AGENT_LIST_FOR_DESKTOP = listOf( - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102" + + " Electron/20.1.1 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) ElementNightly/2022091301 Chrome/104.0.5112.102 Electron/20.1.1 Safari/537.36", ) private val AN_EXPECTED_RESULT_LIST_FOR_DESKTOP = listOf( From 8663fe8c74f8796b4a9645b79fa2262588554705 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 29 Sep 2022 12:35:15 +0300 Subject: [PATCH 058/136] Add tests for unknown user agents. --- .../v2/ParseDeviceUserAgentUseCaseTest.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt index 0cc59f1d14..4797a079a2 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/ParseDeviceUserAgentUseCaseTest.kt @@ -88,6 +88,15 @@ private val AN_EXPECTED_RESULT_LIST_FOR_WEB = listOf( DeviceUserAgent(DeviceType.WEB, "Edge", "Windows NT 10.0", null, null), ) +private val AN_UNKNOWN_USER_AGENT_LIST = listOf( + "AppleTV11,1/11.1", + "Curl Client/1.0", +) +private val AN_UNKNOWN_USER_AGENT_EXPECTED_RESULT_LIST = listOf( + DeviceUserAgent(DeviceType.UNKNOWN, null, null, null, null), + DeviceUserAgent(DeviceType.UNKNOWN, null, null, null, null), +) + class ParseDeviceUserAgentUseCaseTest { private val parseDeviceUserAgentUseCase = ParseDeviceUserAgentUseCase() @@ -119,4 +128,11 @@ class ParseDeviceUserAgentUseCaseTest { parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_EXPECTED_RESULT_LIST_FOR_WEB[index] } } + + @Test + fun `given an unknown user agent then it should be parsed as expected`() { + AN_UNKNOWN_USER_AGENT_LIST.forEachIndexed { index, userAgent -> + parseDeviceUserAgentUseCase.execute(userAgent) shouldBeEqualTo AN_UNKNOWN_USER_AGENT_EXPECTED_RESULT_LIST[index] + } + } } From 38cd2be33223a1dc9af5be9b33cd4a616df9e9f2 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 29 Sep 2022 13:28:46 +0300 Subject: [PATCH 059/136] Fix broken tests. --- .../v2/GetDeviceFullInfoListUseCase.kt | 2 +- .../v2/overview/GetDeviceFullInfoUseCase.kt | 2 +- .../v2/GetDeviceFullInfoListUseCaseTest.kt | 19 ++++++++++++++++--- .../overview/GetDeviceFullInfoUseCaseTest.kt | 3 ++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt index e4cdbb0a87..0272bea351 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt @@ -73,7 +73,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor( val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoDeviceInfo?.deviceId - val deviceUserAgent = parseDeviceUserAgentUseCase.execute(deviceInfo.lastSeenUserAgent) + val deviceUserAgent = parseDeviceUserAgentUseCase.execute(deviceInfo.getBestLastSeenUserAgent()) DeviceFullInfo(deviceInfo, cryptoDeviceInfo, roomEncryptionTrustLevel, isInactive, isCurrentDevice, deviceUserAgent) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt index fd612308fc..9ed77d3834 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCase.kt @@ -51,7 +51,7 @@ class GetDeviceFullInfoUseCase @Inject constructor( val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo) val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs ?: 0) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoInfo.deviceId - val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.lastSeenUserAgent) + val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.getBestLastSeenUserAgent()) DeviceFullInfo( deviceInfo = info, cryptoDeviceInfo = cryptoInfo, diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt index 0537e4f652..3422a01694 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt @@ -46,6 +46,7 @@ private const val A_DEVICE_ID_3 = "device-id-3" private const val A_TIMESTAMP_1 = 100L private const val A_TIMESTAMP_2 = 200L private const val A_TIMESTAMP_3 = 300L +private const val A_USER_AGENT = "Element dbg/1.5.0-dev (Xiaomi Mi 9T; Android 11; RKQ1.200826.002 test-keys; Flavour GooglePlay; MatrixAndroidSdk2 1.5.2)" class GetDeviceFullInfoListUseCaseTest { @@ -90,21 +91,24 @@ class GetDeviceFullInfoListUseCaseTest { lastSeenTs = A_TIMESTAMP_1, isInactive = true, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, - cryptoDeviceInfo = cryptoDeviceInfo1 + cryptoDeviceInfo = cryptoDeviceInfo1, + lastSeenUserAgent = A_USER_AGENT ) val deviceInfo2 = givenADevicesInfo( deviceId = A_DEVICE_ID_2, lastSeenTs = A_TIMESTAMP_2, isInactive = false, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Trusted, - cryptoDeviceInfo = cryptoDeviceInfo2 + cryptoDeviceInfo = cryptoDeviceInfo2, + lastSeenUserAgent = A_USER_AGENT ) val deviceInfo3 = givenADevicesInfo( deviceId = A_DEVICE_ID_3, lastSeenTs = A_TIMESTAMP_3, isInactive = false, roomEncryptionTrustLevel = RoomEncryptionTrustLevel.Warning, - cryptoDeviceInfo = cryptoDeviceInfo3 + cryptoDeviceInfo = cryptoDeviceInfo3, + lastSeenUserAgent = A_USER_AGENT ) val deviceInfoList = listOf(deviceInfo1, deviceInfo2, deviceInfo3) every { fakeFlowSession.liveMyDevicesInfo() } returns flowOf(deviceInfoList) @@ -188,12 +192,21 @@ class GetDeviceFullInfoListUseCaseTest { isInactive: Boolean, roomEncryptionTrustLevel: RoomEncryptionTrustLevel, cryptoDeviceInfo: CryptoDeviceInfo, + lastSeenUserAgent: String, ): DeviceInfo { val deviceInfo = mockk() every { deviceInfo.deviceId } returns deviceId every { deviceInfo.lastSeenTs } returns lastSeenTs + every { deviceInfo.getBestLastSeenUserAgent() } returns lastSeenUserAgent every { getEncryptionTrustLevelForDeviceUseCase.execute(any(), cryptoDeviceInfo) } returns roomEncryptionTrustLevel every { checkIfSessionIsInactiveUseCase.execute(lastSeenTs) } returns isInactive + every { parseDeviceUserAgentUseCase.execute(lastSeenUserAgent) } returns DeviceUserAgent( + DeviceType.MOBILE, + "Xiaomi Mi 9T", + "Android 11", + "Element dbg", + "1.5.0-dev" + ) return deviceInfo } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt index 392c737152..425935d065 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/GetDeviceFullInfoUseCaseTest.kt @@ -81,7 +81,7 @@ class GetDeviceFullInfoUseCaseTest { // Given val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo() val deviceInfo = DeviceInfo( - lastSeenTs = A_TIMESTAMP + lastSeenTs = A_TIMESTAMP, ) fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData = MutableLiveData(Optional(deviceInfo)) fakeActiveSessionHolder.fakeSession.fakeCryptoService.myDevicesInfoWithIdLiveData.givenAsFlow() @@ -92,6 +92,7 @@ class GetDeviceFullInfoUseCaseTest { val isInactive = false val isCurrentDevice = true every { checkIfSessionIsInactiveUseCase.execute(any()) } returns isInactive + every { parseDeviceUserAgentUseCase.execute(any()) } returns DeviceUserAgent(DeviceType.MOBILE) // When val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull() From 6eb5d9818094a81aae7d2ec7ae5721a58fe17b4b Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 12 Sep 2022 14:14:45 +0200 Subject: [PATCH 060/136] Add changelog entry --- changelog.d/7100.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7100.wip diff --git a/changelog.d/7100.wip b/changelog.d/7100.wip new file mode 100644 index 0000000000..47e7a6f810 --- /dev/null +++ b/changelog.d/7100.wip @@ -0,0 +1 @@ +[Device Management] Learn more bottom sheets From 70a5093e3d82eae12af70bdeb7378c31efcb209a Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 12 Sep 2022 14:37:38 +0200 Subject: [PATCH 061/136] Adding string resources --- library/ui-strings/src/main/res/values/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 4ff7aae750..2170ec6c5b 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3302,6 +3302,10 @@ Session name Custom session names can help you recognize your devices more easily. Please be aware that session names are also visible to people you communicate with. + Inactive sessions are sessions you have not used in some time. Removing inactive sessions can improve performance, and make it easier for you to identify if a new session is suspicious. In addition, inactive sessions continue to receive encryption keys and so may pose a security or privacy risk if an unauthorised person is able to access the session. + Unverified sessions are sessions that have logged in with your credentials but not been verified via cross-verification from a verified session, or using your passphrase. You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account. If you do recognise them, you should verify them as this allows your contacts to see that the new login is really you. + This session has logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying from another verified session. This means it holds encryption keys for your previous messages, and confirms to other users you are communicating with that the session is really you. + Other users in direct messages and rooms that you join are able to view a full list of your sessions, including which are verified and unverified. This provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here. %s\nis looking a little empty. From 1d11eae0cc69a98594fdbc9d96ae1177f547fa14 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 12 Sep 2022 14:54:26 +0200 Subject: [PATCH 062/136] Removing learn more link from security header --- .../values/stylable_sessions_list_header_view.xml | 1 + .../devices/v2/list/SessionsListHeaderView.kt | 13 +++++++++++-- .../main/res/layout/fragment_settings_devices.xml | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml b/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml index d3b931e44a..098ec263fc 100644 --- a/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml +++ b/library/ui-styles/src/main/res/values/stylable_sessions_list_header_view.xml @@ -4,6 +4,7 @@ + diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt index ef8682df01..0264db08e1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionsListHeaderView.kt @@ -65,14 +65,23 @@ class SessionsListHeaderView @JvmOverloads constructor( return } + val hasLearnMoreLink = typedArray.getBoolean(R.styleable.SessionsListHeaderView_sessionsListHeaderHasLearnMoreLink, true) + if(hasLearnMoreLink) { + setDescriptionWithLearnMore(description) + } else { + binding.sessionsListHeaderDescription.text = description + } + + binding.sessionsListHeaderDescription.isVisible = true + } + + private fun setDescriptionWithLearnMore(description: String) { val learnMore = context.getString(R.string.action_learn_more) val fullDescription = buildString { append(description) append(" ") append(learnMore) } - - binding.sessionsListHeaderDescription.isVisible = true binding.sessionsListHeaderDescription.setTextWithColoredPart( fullText = fullDescription, coloredPart = learnMore, diff --git a/vector/src/main/res/layout/fragment_settings_devices.xml b/vector/src/main/res/layout/fragment_settings_devices.xml index 8e2daa2239..4f4e14eaad 100644 --- a/vector/src/main/res/layout/fragment_settings_devices.xml +++ b/vector/src/main/res/layout/fragment_settings_devices.xml @@ -14,6 +14,7 @@ android:layout_height="wrap_content" app:sessionsListHeaderDescription="@string/device_manager_header_section_security_recommendations_description" app:sessionsListHeaderTitle="@string/device_manager_header_section_security_recommendations_title" + app:sessionsListHeaderHasLearnMoreLink="false" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -62,6 +63,7 @@ android:layout_height="wrap_content" app:sessionsListHeaderDescription="" app:sessionsListHeaderTitle="@string/device_manager_current_session_title" + app:sessionsListHeaderHasLearnMoreLink="false" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/deviceListSecurityRecommendationsDivider" /> @@ -92,6 +94,7 @@ android:layout_height="wrap_content" app:sessionsListHeaderDescription="@string/device_manager_sessions_other_description" app:sessionsListHeaderTitle="@string/device_manager_sessions_other_title" + app:sessionsListHeaderHasLearnMoreLink="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/deviceListDividerCurrentSession" /> From 648311e2b10b7fb3528053394e915d95a3e11c46 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 12 Sep 2022 15:54:15 +0200 Subject: [PATCH 063/136] Show basic bottom sheet when pressing learn more link from other sessions section --- .../src/main/res/values-ca/strings.xml | 4 +- .../src/main/res/values-cs/strings.xml | 2 +- .../src/main/res/values-de/strings.xml | 2 +- .../src/main/res/values-et/strings.xml | 2 +- .../src/main/res/values-fa/strings.xml | 4 +- .../src/main/res/values-fr/strings.xml | 2 +- .../src/main/res/values-hu/strings.xml | 2 +- .../src/main/res/values-in/strings.xml | 2 +- .../src/main/res/values-it/strings.xml | 2 +- .../src/main/res/values-nl/strings.xml | 2 +- .../src/main/res/values-pl/strings.xml | 2 +- .../src/main/res/values-pt-rBR/strings.xml | 2 +- .../src/main/res/values-ru/strings.xml | 2 +- .../src/main/res/values-sk/strings.xml | 2 +- .../src/main/res/values-uk/strings.xml | 2 +- .../src/main/res/values-zh-rCN/strings.xml | 2 +- .../src/main/res/values-zh-rTW/strings.xml | 2 +- .../src/main/res/values/strings.xml | 6 +- .../app/core/di/MavericksViewModelModule.kt | 6 ++ .../v2/VectorSettingsDevicesFragment.kt | 18 +++++- .../v2/more/SessionLearnMoreBottomSheet.kt | 62 +++++++++++++++++++ .../v2/more/SessionLearnMoreViewModel.kt | 43 +++++++++++++ .../v2/more/SessionLearnMoreViewState.kt | 29 +++++++++ .../bottom_sheet_session_learn_more.xml | 45 ++++++++++++++ 24 files changed, 222 insertions(+), 25 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewState.kt create mode 100644 vector/src/main/res/layout/bottom_sheet_session_learn_more.xml 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 863fa13fbb..daeebf6b30 100644 --- a/library/ui-strings/src/main/res/values-ca/strings.xml +++ b/library/ui-strings/src/main/res/values-ca/strings.xml @@ -2604,7 +2604,7 @@ Explora sales Per estar més segur, verifica les teves sessions i tanca qualsevol sessió que no reconeguis o ja no utilitzis. Altres sessions - Sessions + Sessions Obre la llista d\'espais Crea un nou xat o sala Gent @@ -2674,4 +2674,4 @@ Aquesta sessió està llesta per a missatges segurs. La teva sessió actual està llesta per a missatges segurs. Verifica la teva sessió actual obtenir missatges segurs millorats. - \ 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 79f8311159..7e6a012c65 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2653,7 +2653,7 @@ Zobrazit všechny relace (V2, WIP) V zájmu co nejlepšího zabezpečení ověřujte své relace a odhlašujte se ze všech relací, které již nepoznáváte nebo nepoužíváte. Ostatní relace - Relace + Relace Seznam otevřených prostorů Vytvořit novou konverzaci nebo místnost Lidé 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 e01fc898a3..0b6d8b9666 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2589,7 +2589,7 @@ Alle Sitzungen anzeigen (V2, in Arbeit) Für bestmögliche Sicherheit verifiziere deine Sitzungen und melde dich von allen ab, die du nicht erkennst oder nutzt. Andere Sitzungen - Sitzungen + Sitzungen Space-Liste öffnen Beginne ein Gespräch oder erstelle einen Raum Favoriten 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 9bd1dd23b7..51882a505a 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2594,7 +2594,7 @@ Näita kõiki sessioone (V2, WIP) Parima turvalisuse nimel verifitseeri kõik oma sessioonid ning logi välja neist, mida sa enam ei kasuta. Muud sessioonid - Sessionid + Sessionid Ava kogukondade loend Alusta uut vestlust või loo uus jututuba Inimesed 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 400a8121f9..1b8d3a4fb3 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2603,7 +2603,7 @@ نمایش تمامی نشست‌ها (ن۲، دح‌ت) برای امنیت بیش‌تر، نشست‌هایتان را تأیید و از هر نشستی که تشخیصش نمی‌دهید یا دیگر استفاده نمی‌کنید خارج شوید. دیگر نشست‌ها - نشست‌ها + نشست‌ها گشودن سیاههٔ فضاها ایجاد اتاق یا گفت‌وگویی جدید افراد @@ -2700,4 +2700,4 @@ ایجاد پیام خصوصی فقط در نخستین پیام المنتی ساده شده با زبانه‌های انتخابی به کار انداختن چینش جدید - \ No newline at end of file + 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 5a19ccf2da..bbd82dd596 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2603,7 +2603,7 @@ Afficher toutes les sessions (V2, en cours) Pour une meilleure sécurité, vérifiez vos sessions et déconnectez toutes les sessions que vous ne connaissez pas ou que vous n’utilisez plus. Autres sessions - Sessions + Sessions Ouvrir la liste des espaces Créer une nouvelle conversation ou salon Personnes 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 3068556fe4..397c2d4662 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2614,7 +2614,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Minden munkamenet megjelenítése (V2, WIP) A legjobb biztonság érdekében ellenőrizd a munkameneteket, és jelentkezz ki minden olyan munkamenetből, melyet már nem ismersz fel vagy nem használsz. Más munkamenetek - Munkamenetek + Munkamenetek Nyitott területek listája Új beszélgetés vagy szoba létrehozása Emberek 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 3b30950bd1..18dbbff4ad 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2555,7 +2555,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tampilkan Semua Sesi (V2, Dalam Pengembangan) Untuk keamanan terbaik, verifikasi sesi Anda dan keluarkan sesi apa pun yang Anda tidak kenal atau Anda tidak gunakan lagi. Sesi lainnya - Sesi + Sesi Buka daftar space Buat percakapan atau ruangan baru Orang 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 b7b0fe91af..8ad2e62821 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2594,7 +2594,7 @@ Mostra tutte le sessioni (V2, WIP) Per una maggiore sicurezza, verifica le tue sessioni e disconnetti quelle che non riconosci o che non usi più. Altre sessioni - Sessioni + Sessioni Apri elenco spazi Crea una nuova conversazione o stanza Persone 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 ce122b0646..c5de4ae5f7 100644 --- a/library/ui-strings/src/main/res/values-nl/strings.xml +++ b/library/ui-strings/src/main/res/values-nl/strings.xml @@ -2602,7 +2602,7 @@ Open instellingen Voor de beste beveiliging verifieert u uw sessies en meldt u zich af bij elke sessie die u niet meer herkent of gebruikt. Andere sessies - Sessies + Sessies Lijst met publieke spaces Nieuw gesprek of nieuwe kamer aanmaken Personen 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 b7b73eb9e6..6deb3dd2e7 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -2699,7 +2699,7 @@ Otwórz ustawienia Aby zapewnić najlepsze bezpieczeństwo, zweryfikuj swoje sesje i wyloguj się z każdej sesji, której już nie rozpoznajesz lub której już nie używasz. Inne sesje - Sesje + Sesje Lista otwartych przestrzeni Utwórz nową rozmowę lub pokój Ludzie 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 817c7646df..1c5291d6f3 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 @@ -2603,7 +2603,7 @@ Mostrar Todas Sessões (V2, WIP) Para a melhor segurança, verifique suas sessões e faça signout de qualquer sessão que você não reconhece ou usa mais. Outras sessões - Sessões + Sessões Abrir lista de espaços Criar uma nova conversa ou sala Todas 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 7c9d073035..718e4cd125 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -2662,7 +2662,7 @@ Все беседы Для лучшей безопасности заверьте свои сессии и выйдите из тех, которые более не признаёте или не используете. Другие сессии - Сессии + Сессии Создать беседу или комнату Показать все сессии (V2, в разработке) Люди 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 9eb22e3ae3..b100db2717 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2653,7 +2653,7 @@ Zobraziť všetky relácie (V2, WIP) V záujme čo najlepšieho zabezpečenia overte svoje relácie a odhláste sa z každej relácie, ktorú už nepoznáte alebo nepoužívate. Iné relácie - Relácie + Relácie Otvoriť zoznam priestorov Vytvoriť novú konverzáciu alebo miestnosť Ľudia 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 3e511f8459..0de8e7191e 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2703,7 +2703,7 @@ Показати всі сеанси (V2, WIP) Для найкращої безпеки перевірте свої сеанси та вийдіть з усіх сеансів, які ви більше не розпізнаєте або не використовуєте. Інші сеанси - Сеанси + Сеанси Відкрити список кімнат Створити нову розмову або кімнату Люди 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 db1dab92e2..56a399482c 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 @@ -2553,7 +2553,7 @@ 显示全部会话(V2, WIP) 为获得最佳安全性,请验证你的会话,并从任何你不认识或不再使用的会话登出。 其他会话 - 会话 + 会话 打开空间列表 创建新对话或房间 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 78caa2cc2e..cfeb6ca915 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 @@ -2553,7 +2553,7 @@ 顯示所有工作階段 (V2, WIP) 為了取得最佳安全性,請驗證您的工作階段並登出任何您無法識別或不再使用的工作階段。 其他工作階段 - 工作階段 + 工作階段 開啟空間清單 建立新的對話或聊天室 聯絡人 diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 2170ec6c5b..40653db278 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2365,9 +2365,6 @@ Show All Sessions Manage Sessions Sign out of this session - Sessions - Other sessions - For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore. Server name Server version @@ -3229,6 +3226,9 @@ Show All Sessions (V2, WIP) + Sessions + Other sessions + For best security, verify your sessions and sign out from any session that you don’t recognize or use anymore. Mobile Web Desktop diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 62e7140742..7a5b95f88e 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -90,6 +90,7 @@ import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet import im.vector.app.features.settings.devices.DevicesViewModel import im.vector.app.features.settings.devices.v2.details.SessionDetailsViewModel import im.vector.app.features.settings.devices.v2.othersessions.OtherSessionsViewModel +import im.vector.app.features.settings.devices.v2.more.SessionLearnMoreViewModel import im.vector.app.features.settings.devices.v2.overview.SessionOverviewViewModel import im.vector.app.features.settings.devices.v2.rename.RenameSessionViewModel import im.vector.app.features.settings.devtools.AccountDataViewModel @@ -659,4 +660,9 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(RenameSessionViewModel::class) fun renameSessionViewModelFactory(factory: RenameSessionViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(SessionLearnMoreViewModel::class) + fun sessionLearnMoreViewModelFactory(factory: SessionLearnMoreViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt index 1e5c4d88e0..885a91b9d7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt @@ -21,7 +21,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import com.airbnb.mvrx.Success @@ -44,6 +43,7 @@ import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INAC import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationView import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState +import im.vector.app.features.settings.devices.v2.more.SessionLearnMoreBottomSheet import javax.inject.Inject /** @@ -76,7 +76,7 @@ class VectorSettingsDevicesFragment : private fun initToolbar() { (activity as? AppCompatActivity) ?.supportActionBar - ?.setTitle(R.string.settings_sessions_list) + ?.setTitle(R.string.device_manager_sessions_list_title) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -157,10 +157,22 @@ class VectorSettingsDevicesFragment : private fun initLearnMoreButtons() { views.deviceListHeaderOtherSessions.onLearnMoreClickListener = { - Toast.makeText(context, "Learn more other", Toast.LENGTH_LONG).show() + showLearnMoreInfoOtherSessions() } } + private fun showLearnMoreInfoOtherSessions() { + val args = SessionLearnMoreBottomSheet.Args( + title = getString(R.string.device_manager_sessions_other_title), + description = buildString { + append(getString(R.string.device_manager_learn_more_sessions_unverified)) + append("\n\n") + append(getString(R.string.device_manager_learn_more_sessions_inactive)) + } + ) + SessionLearnMoreBottomSheet.show(childFragmentManager, args) + } + private fun cleanUpLearnMoreButtonsListeners() { views.deviceListHeaderOtherSessions.onLearnMoreClickListener = null } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt new file mode 100644 index 0000000000..5846c8aa0b --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.more + +import android.os.Parcelable +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.FragmentManager +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetSessionLearnMoreBinding +import kotlinx.parcelize.Parcelize + +@AndroidEntryPoint +class SessionLearnMoreBottomSheet : VectorBaseBottomSheetDialogFragment() { + + @Parcelize + data class Args( + val title: String, + val description: String, + ) : Parcelable + + private val viewModel: SessionLearnMoreViewModel by fragmentViewModel() + + override val showExpanded = true + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetSessionLearnMoreBinding { + return BottomSheetSessionLearnMoreBinding.inflate(inflater, container, false) + } + + override fun invalidate() = withState(viewModel) { viewState -> + super.invalidate() + views.bottomSheetSessionLearnMoreTitle.text = viewState.title + views.bottomSheetSessionLearnMoreDescription.text = viewState.description + } + + companion object { + + fun show(fragmentManager: FragmentManager, args: Args) { + val bottomSheet = SessionLearnMoreBottomSheet() + bottomSheet.isCancelable = true + bottomSheet.setArguments(args) + bottomSheet.show(fragmentManager, "SessionLearnMoreBottomSheet") + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewModel.kt new file mode 100644 index 0000000000..09ca2df15d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewModel.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.more + +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory +import im.vector.app.core.platform.EmptyAction +import im.vector.app.core.platform.EmptyViewEvents +import im.vector.app.core.platform.VectorViewModel + +class SessionLearnMoreViewModel @AssistedInject constructor( + @Assisted initialState: SessionLearnMoreViewState, +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: SessionLearnMoreViewState): SessionLearnMoreViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + override fun handle(action: EmptyAction) { + // do nothing + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewState.kt new file mode 100644 index 0000000000..cade2ce861 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreViewState.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.more + +import com.airbnb.mvrx.MavericksState + +data class SessionLearnMoreViewState( + val title: String, + val description: String, +) : MavericksState { + constructor(args: SessionLearnMoreBottomSheet.Args) : this( + title = args.title, + description = args.description, + ) +} diff --git a/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml b/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml new file mode 100644 index 0000000000..bdfa4b3c1a --- /dev/null +++ b/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + From 97cdda45d6692a6f0841f2bdcab18ab7ca8b918e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Mon, 12 Sep 2022 17:14:31 +0200 Subject: [PATCH 064/136] Adding close button --- library/ui-strings/src/main/res/values/strings.xml | 1 + .../devices/v2/more/SessionLearnMoreBottomSheet.kt | 13 +++++++++++++ .../res/layout/bottom_sheet_session_learn_more.xml | 14 +++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 40653db278..8ae869639a 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -406,6 +406,7 @@ Reset Learn more Next + Got it Copied to clipboard diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt index 5846c8aa0b..22ca06eb1e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/more/SessionLearnMoreBottomSheet.kt @@ -16,8 +16,10 @@ package im.vector.app.features.settings.devices.v2.more +import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.fragment.app.FragmentManager import com.airbnb.mvrx.fragmentViewModel @@ -44,6 +46,17 @@ class SessionLearnMoreBottomSheet : VectorBaseBottomSheetDialogFragment super.invalidate() views.bottomSheetSessionLearnMoreTitle.text = viewState.title diff --git a/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml b/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml index bdfa4b3c1a..72e1bbdf23 100644 --- a/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml +++ b/vector/src/main/res/layout/bottom_sheet_session_learn_more.xml @@ -34,12 +34,24 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@id/bottomSheetSessionLearnMoreCloseButton" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/bottomSheetSessionLearnMoreTitle" tools:text="Further context on verified sessions. What do those mean, and how do they differ from unverified ones." /> +