From cbb80785f194c4feb4b2dabaa162c68707238eb5 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Sat, 3 Dec 2022 15:55:14 +0000 Subject: [PATCH 001/246] Translated using Weblate (Persian) Currently translated at 99.8% (2553 of 2558 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 | 4 ++++ 1 file changed, 4 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 a3a74df10f..720a3a28fb 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2849,4 +2849,8 @@ لطفاً مطمئن شوید که مبدأ این کد را می‌دانید. با پیوند دادن افزاره‌ها، دسترسی کامل را به حسابتان می‌دهید. نمایش گپ‌های اخیر در فهرست هم رسانی سامانه به کار انداختن هم‌رسانی مستقیم + درخواست این که صفحه‌کلید نباید هیچ دادهٔ شخصی‌ شده‌ای را مانند نوشتن تاریخچه و واژه‌نامه برپایهٔ آن‌چه در گفت‌وگوها می‌نویسید به‌روز کند. توجّه داشته باشید که ممکن است برخی صفحه‌کلیدها به این تنظیمات احترام نگذارند. + ${app_name} برای نمایش آگاهی‌ها نیازمند اجازه است. آگاهی می‌تواندد پیام‌ها، دعوت‌ها و…تان را نشان دهند. +\n +\nلطفا در بیرون‌پریدنی بعدی اجازهٔ دسترسی بدهید تا بتوانید آگاهی‌ها را ببینید. \ No newline at end of file From 4488061408dd42322ca9739120e5a42678bc8f18 Mon Sep 17 00:00:00 2001 From: Didek Date: Mon, 5 Dec 2022 03:18:10 +0000 Subject: [PATCH 002/246] Translated using Weblate (Polish) Currently translated at 92.7% (2372 of 2558 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- .../src/main/res/values-pl/strings.xml | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) 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 1c01c82189..e615950931 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -345,7 +345,7 @@ Importuj klucze z lokalnego pliku Importuj Szyfruj wiadomości tylko do zaufanych sesji - Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych sesji w tym pokoju z tej sesji. + Nigdy nie wysyłaj szyfrowanych wiadomości do sesji (np urządzeń innych użytkowników) które nie zostały zweryfikowane. Aby sprawdzić czy ta sesja jest zaufana, skontaktuj się z jej właścicielem używając innych form (np. osobiście lub telefonicznie) i zapytaj czy klucz, który widzą w ustawieniach użytkownika dla tego urządzenia pasuje do klucza poniżej: Jeśli klucz pasuje, potwierdź to przyciskiem poniżej. Jeśli nie, to ktoś inny najprawdopodobniej przejmuje lub podszywa się pod tą sesję i powinieneś dodać tę sesję do czarnej listy. W przyszłości proces weryfikacji będzie bardziej skomplikowany. Wyślij naklejkę @@ -622,7 +622,7 @@ Brak sieci. Sprawdź swoje połączenie z Internetem. Proszę czekać… Tego pokoju nie można podejrzeć - Bezpieczeństwo i Prywatność + Bezpieczeństwo i prywatność Brak reguł push Oczekiwanie… Wysyłanie miniatury (%1$s / %2$s) @@ -2398,7 +2398,7 @@ Wybierz, gdzie prowadzone są Twoje rozmowy, dając Ci kontrolę i niezależność. Połączenie przez sieć Matrix. Bezpieczna i niezależna komunikacja, która zapewnia ten sam poziom prywatności, co rozmowa twarzą w twarz we własnym domu. Komunikacja dla Twojego zespołu. - Położenie + Lokalizacja Zagadnienia prawne Już przeglądasz ten wątek! Wyświetl w pokoju @@ -2743,4 +2743,48 @@ %s \nwygląda nieco pusto. Brak przestrzeni. + ⚠ W tym pokoju znajdują się użytkownicy ze niezweryfikowanymi urządzeniami, nie będą one mogły odszyfrować wiadomości które wysyłasz. + Udziel Uprawnień + ${app_name} potrzebuje uprawnień aby wyświetlać powiadomienia. +\nProszę udziel uprawnień. + ${app_name} potrzebuje uprawnień by wyświetlić powiadomienia. Będą one pokazywać twoje wiadomości, zaproszenia, itd. +\n +\nProszę zezwól na dostęp na następnym pop-upie aby móc zobaczyć powiadomienia. + Tutaj będą twoje nowe zaproszenia. + Brak zaproszeń. + Nigdy nie wysyłaj zaszyfrowanych wiadomości do niezweryfikowanych sesji w tym pokoju. + Wyloguj się z tej sesji + + Wyloguj się z %1$d sesji + Wyloguj się z %1$d sesji + + + + Wyloguj się + Wybierz sesje + Pokaż adres IP + Niezweryfikowane sesje + Brak niezweryfikowanych sesji. + Zweryfikuj swoje sesje dla zwiększenia bezpieczeństwa wiadomości lub wyloguj się z tych których nie rozpoznajesz lub już nie używasz. + Niezweryfikowane + Zweryfikuj te sesje lub wyloguj się z nich. + Niezweryfikowane sesje + Popraw swoje bezpieczeństwo stosując te zalecenia. + Zalecenia bezpieczenstwa + Pokaż ostatnie rozmowy w systemowym menu udostępniania + Bezpośrednie udostępnianie + Bądź w stanie nagrywać i wysyłać transmisje głosowe na osi czasu pokoju. + Włącz transmicje głosowe (w trakcie aktywnego rozwoju) + Zachowuj nazwę aplikacji, wersję oraz jej url aby łatwiej rozpoznawać je w menedzerze sesji. + Włącz rejestrowanie informacji o kliencie + Miej lepszą kontrolę nad zalogowanymi sesjami. + Włącz nowy manager sesji + Wypróbuj zaawansowany edytor tekstu (tryb zwykłego tekstu dostępny wkrótce) + Włącz zaawansowany edytor tekstu + Formatowanie tekstu + Ankiety + Transmisja Głosowa + Załączniki + Naklejki + Galeria \ No newline at end of file From 0754409394786cf2e9f12dc60d4108d7f2ddd4f3 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sun, 4 Dec 2022 01:55:39 +0000 Subject: [PATCH 003/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2558 of 2558 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- library/ui-strings/src/main/res/values-pt-rBR/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 8129a234fb..62cdb134d6 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 @@ -2814,7 +2814,7 @@ A requisição falhou. Seja capaz de gravar e enviar broadcast de voz em timeline de sala. Broadcast de voz (sob desenvolvimento ativo) - Buffering + Buffering… Pausar broadcast de voz Tocar ou retomar broadcast de voz Parar gravação de broadcast de voz @@ -2866,4 +2866,6 @@ Citando Respondendo a %s Editando + Mostrar chats recentes no menu de compartilhar do sistema + Habilitar compartilhar direto \ No newline at end of file From eb5aad70778b426782361364958c72b6c24b2e46 Mon Sep 17 00:00:00 2001 From: Platon Terekhov Date: Sun, 4 Dec 2022 18:42:47 +0000 Subject: [PATCH 004/246] Translated using Weblate (Russian) Currently translated at 100.0% (2558 of 2558 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 39d1c8de2b..d99d0bf9f4 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -2921,7 +2921,7 @@ Не получилось начать новую голосовую трансляцию Перемотать вперёд на 30 секунд Перемотать назад на 30 секунд - Буферизация + Буферизация… Приостановить голосовую трансляцию Проиграть или продолжить голосовую трансляцию Остановить запись голосовой трансляции @@ -2963,4 +2963,6 @@ Цитируя В ответ на %s Редактирование + Показывать последние беседы в системном меню распостранения + Включить прямое распостранение \ No newline at end of file From b1722ebaece383f5adea3fc5173b43b2c79d2502 Mon Sep 17 00:00:00 2001 From: phardyle Date: Mon, 5 Dec 2022 09:49:38 +0000 Subject: [PATCH 005/246] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (2558 of 2558 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 | 170 +++++++++--------- 1 file changed, 89 insertions(+), 81 deletions(-) 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 0a01610c36..f619864733 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 @@ -94,12 +94,12 @@ 你撤回了对 %1$s 的邀请 你更换了你的头像 你将你的显示名称设置为 %1$s - 您将显示名称从 %1$s 更改为 %2$s - 您移除了您的显示名称(%1$s) - 您将话题更改为:%1$s + 你将显示名称从 %1$s 更改为 %2$s + 你移除了你的显示名称(%1$s) + 你将话题更改为:%1$s %1$s 更改了房间头像 你更改了房间头像 - 您将房间名称更改为:%1$s + 你将房间名称更改为:%1$s 你发起了一次视频通话。 你发起了一次语音通话。 %s 发送了数据以建立通话。 @@ -126,7 +126,7 @@ 默认 自定义(%1$d) 自定义 - 您更改了 %1$s 的权限等级。 + 你更改了 %1$s 的权限等级。 %1$s 更改了 %2$s 的权限等级。 %1$s 从 %2$s 到 %3$s 你的邀请。理由:%1$s @@ -340,7 +340,7 @@ \n \n请在接下来的弹出窗口中授权允许访问,以便进行通话。 移除 - 您将无法撤消此更改,因为您正在将用户提升为与您相同的权限级别。 + 你将无法撤消此更改,因为你正在将用户提升为与你相同的权限级别。 \n你确定吗? 这可能意味着有人正在恶意劫持你的流量,或者你的手机不信任远程服务器提供的数字证书。 如果服务器管理员说这是预期的情况,请确保下面的指纹与管理员提供的指纹相匹配。 @@ -444,7 +444,7 @@ 已加密消息 响铃通知 静默通知 - 数据收集 + 数据分析 响铃 正在加载…… 你确定要发起语音通话吗? @@ -485,8 +485,8 @@ %1$s 条在 %2$s 中 停用账户 停用我的账户 - 发送统计分析数据 - ${app_name} 会收集匿名统计数据来帮助我们改进程序。 + 发送数据分析数据 + ${app_name}收集匿名数据分析以允许我们改进应用。 停用账户 这将使你的账户永远不再可用。你将无法登录,也不能使用相同的用户 ID 重新注册。你的账户将退出所有已加入的房间,你在身份服务器上的账户信息也会被删除。<b>此操作是不可逆的。</b> \n @@ -628,7 +628,7 @@ 使用密钥备份 如果你此时登出账户,你将会失去你的已加密消息 密钥备份进行中。如果你此时登出账户将无法再访问你的已加密消息。 - 安全密钥备份应该在您的所有会话中都处于活动状态,以避免失去对加密消息的访问权限。 + 安全密钥备份应该在你的所有会话中都处于活动状态,以避免失去对加密消息的访问权限。 我不想要我的已加密消息 正在备份密钥…… 确定吗? @@ -786,7 +786,7 @@ 已验证! 了解了 验证请求 - %s 想验证您的会话 + %s 想验证你的会话 未知错误 编辑 回复 @@ -837,7 +837,7 @@ 通知 ${app_name} 呼叫失败 无法建立实时连接。 -\n请让您的主服务器的管理员配置一个 TURN 服务器,以便呼叫能够可靠地工作。 +\n请让你的主服务器的管理员配置一个 TURN 服务器,以便呼叫能够可靠地工作。 选择声音设备 电话 扬声器 @@ -882,7 +882,7 @@ 应用在后台时你不会收到消息通知。 集成 使用集成管理器来管理机器人、桥接、小部件和贴纸包。 -\n集成管理器接收配置数据,并可以代表您修改小部件、发送房间邀请和设置权限等级。 +\n集成管理器接收配置数据,并可以代表你修改小部件、发送房间邀请和设置权限等级。 安全备份 设置安全备份 重置安全备份 @@ -993,10 +993,10 @@ 可发现的电子邮件地址 发现选项将在你添加电子邮件地址后出现。 发现选项将在你添加电话号码后出现。 - 与您的身份服务器断开连接意味着您将不会被其他用户发现,并且您将无法通过电子邮件或电话邀请其他人。 + 与你的身份服务器断开连接意味着你将不会被其他用户发现,并且你将无法通过电子邮件或电话邀请其他人。 可发现电话号码 我们向%s发送了一封电子邮件,请检查你的电子邮件并点击确认链接 - 我们向 %s 发送了一封电子邮件,请先检查您的电子邮件并点击确认链接 + 我们向 %s 发送了一封电子邮件,请先检查你的电子邮件并点击确认链接 输入身份服务器 URL 无法连接到身份服务器 请输入身份服务器 url @@ -1004,10 +1004,10 @@ 你选择的身份服务器无任何服务条款。仅在你信任服务所有者时继续 已向 %s 发送文字消息。请输入它包含的验证码。 验证码不正确。 - 您当前在身份服务器 %1$s 上共享电子邮件地址或电话号码。您需要重新连接到 %2$s 才能停止共享它们。 + 你当前在身份服务器 %1$s 上共享电子邮件地址或电话号码。你需要重新连接到 %2$s 才能停止共享它们。 同意身份服务器 (%s) 服务条款使你可以通过电子邮件地址或电话号码被发现。 启用详细日志。 - 详细日志将通过在您发送愤怒摇动(RageShake)时提供更多日志来帮助开发人员。即使启用,应用程序也不会记录消息内容或任何其他私人数据。 + 详细日志将通过在你发送愤怒摇动(RageShake)时提供更多日志来帮助开发人员。即使启用,应用程序也不会记录消息内容或任何其他私人数据。 接收你的主服务器条款和条件后请重试。 服务器似乎响应时间太长,这可能是由于连接不良或服务器错误引起的。请稍后再试。 发送附件 @@ -1199,7 +1199,7 @@ 除非你登录以恢复加密密钥,否则你将无法访问安全消息。 当前会话用于用户 %1$s 而你提供了用户 %2$s 的凭证。${app_name} 不支持此功能。 \n请先清除数据,然后重新登录另一个账户。 - 您的 matrix.to 链接格式错误 + 你的 matrix.to 链接格式错误 描述太短 初始同步… 高级设置 @@ -1368,7 +1368,7 @@ \n- 设备使用的网络连接 \n \n我们推荐你在设置中立即更换你的密码和恢复密钥。 - 已取消验证。 您可以重新开始验证。 + 已取消验证。 你可以重新开始验证。 验证已取消 恢复口令词组 消息密钥 @@ -1444,7 +1444,7 @@ 启用此设置会将 FLAG_SECURE 添加到所有活动项。重新启动应用程序以使更改生效。 无法保存媒体文件 设置新账户密码…… - 在您的其它设备上使用最新的 ${app_name}、${app_name} Web、${app_name} Desktop、${app_name} iOS、${app_name} for Android 或其他支持交叉签名的 Matrix 客户端 + 在你的其它设备上使用最新的 ${app_name}、${app_name} Web、${app_name} Desktop、${app_name} iOS、${app_name} for Android 或其他支持交叉签名的 Matrix 客户端 ${app_name} Web \n${app_name} Desktop ${app_name} iOS @@ -1531,7 +1531,7 @@ 你无法访问此消息因为发送者有意不发送密钥 正在等待加密历史 Riot 现已成为 Element! - 我们很高兴地宣布我们已经更名了!您的应用程序是最新的,并且您已登录到您的帐户。 + 我们很高兴地宣布我们已经更名了!你的应用程序是最新的,并且你已登录到你的账户。 明白了 了解更多 将恢复密钥保存到 @@ -1588,7 +1588,7 @@ 移除 %s? 请确认你已点击我们向你发送的电子邮件中的链接。 电子邮件和电话号码 - 管理与您的 Matrix 帐户链接的电子邮件地址和电话号码 + 管理与你的 Matrix 账户链接的电子邮件地址和电话号码 代码 请使用国际格式(电话号码必须以“+”开头) 验证此登录来确认你的身份,授权其访问加密消息。 @@ -1634,7 +1634,7 @@ \n \n你的消息受加密保护,并且只有你和消息接收者拥有唯一解密密钥。 此处的消息未经端到端加密。 - 此主服务器正在运行旧版本。 请让您的主服务器管理员升级。 您可以继续,但某些功能可能无法正常工作。 + 此主服务器正在运行旧版本。 请让你的主服务器管理员升级。 你可以继续,但某些功能可能无法正常工作。 你将此房间设为仅邀请。 %1$s 仅发出此邀请。 在加密房间显示完整历史 @@ -1738,7 +1738,7 @@ 使用 /confetti 命令或发送包含 ❄️ 或 🎉 的消息 显示聊天效果 更改话题 - 更新房间 + 升级房间 发送 m.room.server_acl 事件 更改权限 更改房间名称 @@ -1758,7 +1758,7 @@ 你没有权限更新更改房间多个部分所需角色 选择更改房间各个部分所需的角色 权限 - 需要查看和更新角色以更改房间多个部分。 + 查看和更新更改房间各个部分所需的角色。 房间权限 此房间不公开。你没有邀请将无法重新加入。 你保持通话 @@ -1904,7 +1904,7 @@ 正在创建空间…… 随机 一般性 - 让我们为他们每个人创建一个房间。 您也可以稍后添加更多内容,包括已经存在的内容。 + 让我们为他们每个人创建一个房间。 你也可以稍后添加更多内容,包括已经存在的内容。 你在做些什么? 我们将会为此创建房间。你也可以在稍后增加更多。 你希望在 %s 中进行哪些讨论? @@ -1935,7 +1935,7 @@ 未检查 打开小部件 屏幕截图 - ${app_name} 需要您输入凭据才能执行此操作。 + ${app_name} 需要你输入凭据才能执行此操作。 呼叫转移时发生错误 先询问 查找电话号码时发生了错误 @@ -2031,7 +2031,7 @@ 空间地址 升级到推荐的房间版本 这个房间运行房间版本 %s,此主服务器已将其标记为不稳定。 - 您需要权限才能升级房间 + 你需要权限才能升级房间 自动更新空间父级 自动邀请用户 你将把此房间从 %1$s 升级到 %2$s。 @@ -2061,13 +2061,13 @@ %d 个未接音频电话 请注意,升级将使房间焕然一新。 所有当前消息都将保留在此存档的房间中。 - 主空间中的任何人都可以找到并加入此房间 - 无需手动邀请所有人。 您可以随时在房间设置中更改此设置。 - %s 中的任何人将可以查找并加入此房间 - 无需手动邀请所有人。 您可以随时在房间设置中更改此设置。 + 主空间中的任何人都可以找到并加入此房间 - 无需手动邀请所有人。 你可以随时在房间设置中更改此设置。 + %s 中的任何人将可以查找并加入此房间 - 无需手动邀请所有人。 你可以随时在房间设置中更改此设置。 语音消息 (%1$s) 语音消息处于活动状态时无法回复或编辑 无法录制语音消息 无法播放此语音消息 - 点按您的录音以停止或收听 + 点按你的录音以停止或收听 剩余 %1$d秒 按住录音,松开发送 删除录音 @@ -2078,7 +2078,7 @@ 录制语音消息 需要升级 语音 - 您可能不知道的其它空间或房间 + 你可能不知道的其它空间或房间 你知道的包含这个房间的空间 决定谁能找到并加入这个房间。 点按即可编辑空间 @@ -2105,9 +2105,9 @@ 可用视频通话 可用语音通话 在 ${app_name} 中直接接收邀请的设置 %s。 - 将此电子邮件地址与您的帐户链接 - 此空间的邀请已发送至与您的帐户无关的 %s - 此房间的邀请已发送至与您的帐户无关的 %s + 将此电子邮件地址与你的账户链接 + 此空间的邀请已发送至与你的账户无关的 %s + 此房间的邀请已发送至与你的账户无关的 %s 你所在的全部房间将显示在主页上。 在主页上显示所有房间 滑动结束通话 @@ -2147,7 +2147,7 @@ 和 %s 视频通话 来电响铃中… 空间 - 将一个空间添加到您管理的任何空间。 + 将一个空间添加到你管理的任何空间。 添加现有空间 添加现有房间 你确定要离开 %s 吗? @@ -2171,14 +2171,14 @@ 空间访问 谁可以访问? 为 %s 启用电子邮件通知 - 要接收带有通知的电子邮件,请将电子邮件地址链接到您的 Matrix 帐户 + 要接收带有通知的电子邮件,请将电子邮件地址链接到你的 Matrix 账户 电子邮件通知 升级空间 更改空间名称 启用空间加密 更改空间主地址 更改空间头像 - 您没有权限更新更改该空间的各个部分所需的角色 + 你没有权限更新更改该空间的各个部分所需的角色 选择更改该空间的各个部分所需的角色 查看和更新更改空间的各个部分所需的角色。 空间权限 @@ -2193,9 +2193,9 @@ 隐藏身份服务器政策 显示身份服务器策略 显示用户信息 - 仅更改您在当前房间的头像 + 仅更改你在当前房间的头像 更改当前房间的头像 - 仅在当前房间更改您的显示昵称 + 仅在当前房间更改你的显示昵称 设置房间名称 停止忽略用户,继续显示他们的消息 忽略用户,隐藏他们的消息 @@ -2203,7 +2203,7 @@ 离线 在线 选择主服务器 - 无法访问 URL %s 上的主服务器。请检查您的链接或手动选择一个主服务器。 + 无法访问 URL %s 上的主服务器。请检查你的链接或手动选择一个主服务器。 侦听通知 需要至少 %1$s 个选项 @@ -2218,13 +2218,13 @@ 创建投票 投票 向%s发送电子邮件地址和电话号码 - 您的联系人是私密的。 要从您的联系人中发现用户,我们需要您的许可才能将联系信息发送到您的身份服务器。 + 你的联系人是私密的。 要从你的联系人中发现用户,我们需要你的许可才能将联系信息发送到你的身份服务器。 已登出此会话! 已离开此房间! 你同意发送此信息吗? - 要发现现有的联系人,你需要将联系人信息(电子邮件地址和电话号码)发送到你的身份服务器。出乎隐私考量,我们会在发送前对您的数据进行散列处理。 + 要发现现有的联系人,你需要将联系人信息(电子邮件地址和电话号码)发送到你的身份服务器。出乎隐私考量,我们会在发送前对你的数据进行散列处理。 不是现在 - 您确定要删除此投票吗?一旦移除,就无法恢复。 + 你确定要删除此投票吗?一旦移除,就无法恢复。 删除投票 投票已结束 投票 @@ -2260,7 +2260,7 @@ 你可以随时在设置中关闭它 我们与第三方共享信息 此处 - 通过共享匿名使用数据,帮助我们识别问题并改进 ${app_name}。为了理解人们如何使用多台设备,我们将生成一个随机标识符,由您的设备共享。 + 通过共享匿名使用数据,帮助我们识别问题并改进 ${app_name}。为了理解人们如何使用多台设备,我们将生成一个随机标识符,由你的设备共享。 \n \n你可以阅读我们所有的条款 %s。 帮助改进 ${app_name} @@ -2286,11 +2286,11 @@ %1$d 更多 - 请注意:这是使用临时实现的实验室功能。这意味着您将无法删除您的位置历史记录,即使您停止与此房间共享您的实时位置,高级用户也将能够看到您的位置历史记录。 + 请注意:这是使用临时实现的实验室功能。这意味着你将无法删除你的位置历史记录,即使你停止与此房间共享你的实时位置,高级用户也将能够看到你的位置历史记录。 当前网关:%s 网关 提供反馈 - 为您的团队发送消息。 + 为你的团队发送消息。 消息列 beta 消息列 为所有消息显示最新资料信息(头像和显示名称)。 @@ -2299,7 +2299,7 @@ 覆盖显示名称颜色 检查你的电子邮件。 电子邮件 - 一切由您掌控。 + 一切由你掌控。 BETA 共享你的实时位置 缩放到当前位置 @@ -2334,7 +2334,7 @@ 共享位置 显示消息气泡 共享位置 - 您需要拥有正确的权限才能在此房间中共享实时位置。 + 你需要拥有正确的权限才能在此房间中共享实时位置。 你没有权限共享实时位置 %1$s 前已更新 临时执行:地点在房间历史中持续存在 @@ -2424,7 +2424,7 @@ 安全传送消息。 向主服务器注册端点token失败: \n%1$s - 消息列有助于使您的对话保持话题并易于跟踪。%s 创建消息列将刷新应用程序。对于某些帐户,这可能需要更长的时间。 + 消息列有助于使你的对话保持话题并易于跟踪。%s 创建消息列将刷新应用程序。对于某些账户,这可能需要更长的时间。 重启应用以使更改生效。 启用 LaTeX 数学 (%1$s) @@ -2446,7 +2446,7 @@ 此空间里的东西 无法启用生物特征识别。 - 生物特征识别被禁用,因为最近添加了新的生物特征识别方法。 您可以在“设置”中再次启用它。 + 生物特征识别被禁用,因为最近添加了新的生物特征识别方法。 你可以在“设置”中再次启用它。 主服务器不接收仅有数字的用户名。 发送你的第一条消息邀请%s聊天 加密配置错误 @@ -2509,7 +2509,7 @@ 自动播放动画图片 端点成功注册到主服务器。 端点注册 - 您的主服务器当前不支持消息列,因此此功能可能不可靠。某些消息列的消息可能无法可靠地使用。 %s 您仍然要启用消息列吗? + 你的主服务器当前不支持消息列,因此此功能可能不可靠。某些消息列的消息可能无法可靠地使用。 %s 你仍然要启用消息列吗? Threads接近Beta了 🎉 来自消息列 实用提示:长按消息并使用“%s”。 @@ -2545,7 +2545,7 @@ 你的服务器地址是什么? 你的对话发生的地方 %1$s 和 %2$s - 电子邮件未验证,请检查您的收件箱 + 电子邮件未验证,请检查你的收件箱 无法加载地图 \n此主服务器可能没有设置好显示地图。 打开设置 @@ -2599,14 +2599,14 @@ 欢迎来到 ${app_name}, \n%s。 - 当您有一些未读消息时,这里会显示您的未读消息。 + 当你有一些未读消息时,这里会显示你的未读消息。 提供反馈 点击右上角查看反馈选项。 试用 空间是对房间和人进行分组的新方式。创建一个空间来开始吧。 启用新布局 IP地址 - 验证您的会话以增强安全消息传递或从您不再识别或不再使用的会话中登出。 + 验证你的会话以增强安全消息传递或从你不再识别或不再使用的会话中登出。 尚未准备好安全收发消息 准备好安全收发消息 已验证 @@ -2624,7 +2624,7 @@ 启用延迟的私聊消息 简化的 Element,带有可选的标签 无痕键盘 - 请求键盘不要根据您在对话中输入的内容更新任何个性化数据,例如输入历史记录和字典。 请注意,某些键盘可能不遵守此设置。 + 请求键盘不要根据你在对话中输入的内容更新任何个性化数据,例如输入历史记录和字典。 请注意,某些键盘可能不遵守此设置。 ${app_name}需要权限来显示通知。通知可以显示消息、邀请等。 \n \n请在下个弹窗允许访问以便查看通知。 @@ -2644,21 +2644,21 @@ 记录客户端名称、版本和网址,以便在会话管理器中更轻松地识别会话。 启用客户端信息记录 对所有会话有更好的可见性和控制。 - 您加入的直接消息和聊天室中的其他用户可以查看您的会话的完整列表。 + 你加入的私聊消息和房间中的其他用户可以查看你的会话的完整列表。 \n -\n这让他们确信他们真的在与您交谈,但这也意味着他们可以看到您在此处输入的会话名称。 +\n这让他们确信他们真的在与你交谈,但这也意味着他们可以看到你在此处输入的会话名称。 重命名会话 - 已验证会话已使用您的凭据登录,然后使用您的安全密码或通过交叉验证进行验证。 + 已验证会话已使用你的凭据登录,然后使用你的安全密码或通过交叉验证进行验证。 \n -\n这意味着他们持有您之前消息的加密密钥,并向您正在与之通信的其他用户确认这些会话确实是您。 - 闲置会话是您一段时间未使用的会话,但它们会继续接收加密密钥。 +\n这意味着他们持有你之前消息的加密密钥,并向你正在与之通信的其他用户确认这些会话确实是你。 + 闲置会话是你一段时间未使用的会话,但它们会继续接收加密密钥。 \n -\n删除闲置会话可以提高安全性和性能,并使您更容易识别新会话是否可疑。 +\n删除闲置会话可以提高安全性和性能,并使你更容易识别新会话是否可疑。 闲置会话 - 您可以使用此设备通过二维码登录移动设备或网络设备。 有两种方法可以做到这一点: + 你可以使用此设备通过二维码登录移动设备或网络设备。 有两种方法可以做到这一点: 使用二维码登录 - 请注意,与您交流的人也可以看到会话名称。 - 自定义会话名称可以帮助您更轻松地识别您的设备。 + 请注意,与你交流的人也可以看到会话名称。 + 自定义会话名称可以帮助你更轻松地识别你的设备。 重命名会话 操作系统 型号 @@ -2679,19 +2679,19 @@ 未找到未验证的会话。 未找到已验证的会话。 - 考虑登出您不再使用的旧会话(%1$d 天或更长时间)。 + 考虑登出你不再使用的旧会话(%1$d 天或更长时间)。 闲置 未验证 - 为获得最佳安全性,请从您不认识或不再使用的任何会话中登出。 + 为获得最佳安全性,请从你不认识或不再使用的任何会话中登出。 已验证 过滤器 闲置 %1$d 天或更长时间 未验证 - 未验证 · 您当前的会话 - 验证您当前的会话以显示此会话的验证状态。 + 未验证 · 你当前的会话 + 验证你当前的会话以显示此会话的验证状态。 未知的验证状态 开始语音广播 正在缓冲…… @@ -2702,7 +2702,7 @@ 应用删除线格式 应用斜体格式 应用粗体格式 - 请确保您知道此代码的来源。 通过链接设备,您将为某人提供对您帐户的完全访问权限。 + 请确保你知道此代码的来源。 通过链接设备,你将为某人提供对你账户的完全访问权限。 确认 再试一次 不匹配? @@ -2717,36 +2717,36 @@ 从登录屏幕开始 选择“显示二维码” 转到设置 -> 安全和隐私 - 在您的其它设备上打开应用程序 + 在你的其它设备上打开应用程序 主服务器不支持二维码登录。 登录已在另一台设备上取消。 该二维码无效。 另一台设备必须登录。 另一台设备已登录。 链接未在规定时间内完成。 - 设置安全消息传递时遇到安全问题。 以下其中一项可能会受到损害:您的家庭服务器; 您的互联网连接; 您的设备; + 设置安全消息传递时遇到安全问题。 以下其中一项可能会受到损害:你的家庭服务器; 你的互联网连接; 你的设备; 请求失败。 该请求在另一台设备上被拒绝。 不支持与此设备链接。 连接不成功 - 检查您已登录的设备,应显示以下代码。 确认以下代码与该设备匹配: + 检查你已登录的设备,应显示以下代码。 确认以下代码与该设备匹配: 已建立安全连接 使用已退出登录的设备扫描下方二维码。 - 使用您已登录的设备扫描下方二维码: + 使用你已登录的设备扫描下方二维码: 使用二维码登录 使用此设备上的相机扫描其它设备上显示的二维码: 扫描二维码 3 2 1 - 为了简化您的 ${app_name},选项卡现在是可选的。 使用右上角的菜单管理它们。 + 为了简化你的 ${app_name},选项卡现在是可选的。 使用右上角的菜单管理它们。 无需报告。 - 适用于团队、朋友和组织的一体化安全聊天应用程序。 创建一个聊天室,或加入一个现有的房间,开始。 + 适用于团队、朋友和组织的一体化安全聊天应用程序。 创建一个聊天或加入一个现有的房间来开始。 空间是一种对房间和人员进行分组的新方式。 使用右下角的按钮添加现有房间或创建新房间。 已验证会话 - 未验证会话是使用您的凭据登录但未经交叉验证的会话。 + 未验证会话是使用你的凭据登录但未经交叉验证的会话。 \n -\n您应特别确定您识别这些会话,因为它们可能代表未经授权使用您的帐户。 +\n你应特别确定你识别这些会话,因为它们可能代表未经授权使用你的账户。 未验证会话 闲置 会话名称 @@ -2766,7 +2766,7 @@ 语音广播 已启用: 会话ID: - 出了点差错。请检查您的网络连接并重试。 + 出了点差错。请检查你的网络连接并重试。 联系人 切换全屏模式 选择会话 @@ -2778,9 +2778,9 @@ 附件 贴纸 照片库 - 您没有在此房间内开始语音广播所需的权限。联系房间管理员升级您的权限。 + 你没有在此房间内开始语音广播所需的权限。联系房间管理员升级你的权限。 其他人已经在录制语音广播。等待他们的语音广播结束以开始新的广播。 - 您已经在录制语音广播。请结束您当前的语音广播以开始新的语音广播。 + 你已经在录制语音广播。请结束你当前的语音广播以开始新的语音广播。 无法开始新的语音广播 快进 30 秒 快退 30 秒 @@ -2804,4 +2804,12 @@ 登出 剩余%1$s + 正在编辑 + 回复给%s + 引用 + 显示IP地址 + 隐藏IP地址 + 回复给 + 启用直接分享 + 在系统分享菜单中显示最近聊天 \ No newline at end of file From f3b0205e17c0d616cf557fdf80c0067140744d73 Mon Sep 17 00:00:00 2001 From: Glandos Date: Sat, 3 Dec 2022 13:09:46 +0000 Subject: [PATCH 006/246] Translated using Weblate (French) Currently translated at 100.0% (83 of 83 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/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105100.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105100.txt b/fastlane/metadata/android/fr-FR/changelogs/40105100.txt new file mode 100644 index 0000000000..9f0d0823b4 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Nouvelle implémentation du mode plein écran pour l’éditeur de texte formaté, et correction de bogues. +Intégralité des changements : https://github.com/vector-im/element-android/releases From c9cd4106363716da7bf9b39295d68cd40b0f30db Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sun, 4 Dec 2022 01:58:48 +0000 Subject: [PATCH 007/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (83 of 83 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/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40105100.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40105100.txt b/fastlane/metadata/android/pt-BR/changelogs/40105100.txt new file mode 100644 index 0000000000..c03bb2b140 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Nova implementação do modo de tela cheia para o Editor de Texto Rico e consertos de bugs. +Changelog completo: https://github.com/vector-im/element-android/releases From 1cfd2383859f88dc90c761b0d4a8671b86e7f53e Mon Sep 17 00:00:00 2001 From: Platon Terekhov Date: Sun, 4 Dec 2022 18:47:55 +0000 Subject: [PATCH 008/246] Translated using Weblate (Russian) Currently translated at 100.0% (83 of 83 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ru/ --- fastlane/metadata/android/ru-RU/changelogs/40105080.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40105100.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40105080.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40105100.txt diff --git a/fastlane/metadata/android/ru-RU/changelogs/40105080.txt b/fastlane/metadata/android/ru-RU/changelogs/40105080.txt new file mode 100644 index 0000000000..42f8b2263d --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40105080.txt @@ -0,0 +1,2 @@ +Главные изменения в этой версии: исправления ошибок и улучшения. +Полный список изменений: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/ru-RU/changelogs/40105100.txt b/fastlane/metadata/android/ru-RU/changelogs/40105100.txt new file mode 100644 index 0000000000..14fb635403 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Главные изменения в этой версии: Новая имплементация полноэкранного режима для расширенного режима текстового редактора и исправления ошибок. +Полный список всех изменений: https://github.com/vector-im/element-android/releases From 4d19ccd0dacdf46a76e981ea9d30535cac4d3e1f Mon Sep 17 00:00:00 2001 From: random Date: Mon, 5 Dec 2022 13:02:17 +0000 Subject: [PATCH 009/246] Translated using Weblate (Italian) Currently translated at 100.0% (83 of 83 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/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40105100.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40105100.txt b/fastlane/metadata/android/it-IT/changelogs/40105100.txt new file mode 100644 index 0000000000..7dc50eab33 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: nuova implementazione della modalità a schermo intero per l'editor in Rich Text e correzione di errori. +Cronologia completa: https://github.com/vector-im/element-android/releases From e71b09dfea7217d9952978c82e250a1ee2e7484a Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Sat, 3 Dec 2022 15:52:12 +0000 Subject: [PATCH 010/246] Translated using Weblate (Persian) Currently translated at 100.0% (83 of 83 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105100.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105100.txt b/fastlane/metadata/android/fa/changelogs/40105100.txt new file mode 100644 index 0000000000..b6a96e2fe8 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105100.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: پیاده‌سازی جدید حالت تمام‌صفحه برای ویرایشگر متن غنی و رفع اشکال‌ها. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 8d0ac95bdcfb776d74b38c34e382ac7e7e316c48 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Mon, 5 Dec 2022 10:29:26 +0000 Subject: [PATCH 011/246] Translated using Weblate (Albanian) Currently translated at 100.0% (83 of 83 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sq/changelogs/40105100.txt diff --git a/fastlane/metadata/android/sq/changelogs/40105100.txt b/fastlane/metadata/android/sq/changelogs/40105100.txt new file mode 100644 index 0000000000..a103977a73 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Sendërtim i ri i mënyrës “Sa krejt ekrani”, për Përpunues Teksti të Pasur, si dhe ndreqje të metash. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases From aa3f13b2c43a7993a89071cd79eea205f3184e74 Mon Sep 17 00:00:00 2001 From: Dertyiula Date: Mon, 12 Dec 2022 05:45:56 +0000 Subject: [PATCH 012/246] Translated using Weblate (Azerbaijani) Currently translated at 5.1% (132 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/az/ --- library/ui-strings/src/main/res/values-az/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/ui-strings/src/main/res/values-az/strings.xml b/library/ui-strings/src/main/res/values-az/strings.xml index 6fe322bdd0..d5ab0adcb3 100644 --- a/library/ui-strings/src/main/res/values-az/strings.xml +++ b/library/ui-strings/src/main/res/values-az/strings.xml @@ -136,4 +136,13 @@ • %s ilə uyğunlaşan serverlərə icazə verildi. Siz %1$s üçün otağa qoşulmaq dəvətin ləğv etdiniz %1$s-ı dəvət etdiniz + Tam ekran rejimini dəyiş + buna cavab olaraq + fayl göndərdi. + səs faylı göndərdi. + səsli mesaj göndərdi. + şəkil göndərdi. + video göndərdi. + stiker göndərdi. + sorğu yaratdı. \ No newline at end of file From d1ff3c605a2b9990ba32c8e61d6f9af9deb452d5 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Mon, 5 Dec 2022 13:23:06 +0000 Subject: [PATCH 013/246] Translated using Weblate (Czech) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 67cc3353aa..63e8caca5d 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2924,4 +2924,6 @@ Úpravy Zobrazit poslední chaty v nabídce sdílení systému Povolit přímé sdílení + Zkontrolujte, zda je váš účet v bezpečí + Máte neověřené relace \ No newline at end of file From 52d9a11e20a2b9214e6a9b7a189d7a75dd1da53d Mon Sep 17 00:00:00 2001 From: Vri Date: Mon, 5 Dec 2022 14:16:43 +0000 Subject: [PATCH 014/246] Translated using Weblate (German) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 809ee477fc..7dcae136b8 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2867,4 +2867,6 @@ IP-Adresse anzeigen Kürzliche Unterhaltungen im Teilen-Menü des Systems anzeigen Direktes Teilen aktivieren + Überprüfe sie, um ein sicheres Konto gewährleisten zu können + Du hast nicht verifizierte Sitzungen \ No newline at end of file From 3a589d7d5404deddd027cc9336469e1ce6c68947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 6 Dec 2022 08:39:25 +0000 Subject: [PATCH 015/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2552 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 96d9650ceb..e82586d074 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -1078,7 +1078,7 @@ Ootamatu viga Kas sa oled kindel\? Kui sa logid välja või kaotad seadme, siis sa ei saa enam lugeda oma krüptitud sõnumeid. - Laen varukoopia versiooni… + Laadin varukoopia versiooni… Selleks, et krüptitud sõnumite ajalugu lukust lahti võtta, kasuta oma taastamiseks mõeldud paroolifraasi kasuta oma taastevõtit Kas sa ei tea oma taastamiseks mõeldud paroolifraasi\? Siis sa võid %s. @@ -1379,7 +1379,7 @@ Selge lugu Vaata lisateavet Salvesta taastevõti järgnevalt - Laen sinu kontaktide loendit… + Laadin sinu kontaktide loendit… Sinu kontaktide loend on tühi Sinu kontaktide loend Tühista kutse @@ -2859,4 +2859,6 @@ koostas küsitluse. Kasuta otsejagamist Näita viimaseid vestlusi süsteemses jagamisvaates + Tagamaks, et su konto on sinu kontrolli all, vaata andmed üle + Sul on verifitseerimata sessioone \ No newline at end of file From cc4ae34d22d248fd1c7f1d9601ff34c84b814648 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 7 Dec 2022 08:43:44 +0000 Subject: [PATCH 016/246] Translated using Weblate (Persian) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/ --- .../src/main/res/values-fa/strings.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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 720a3a28fb..1d16e7d29f 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -1,5 +1,5 @@ - + دعوت %s ‫%1$s، %2$s را دعوت کرد %1$s دعوتتان کرد @@ -2853,4 +2853,21 @@ ${app_name} برای نمایش آگاهی‌ها نیازمند اجازه است. آگاهی می‌تواندد پیام‌ها، دعوت‌ها و…تان را نشان دهند. \n \nلطفا در بیرون‌پریدنی بعدی اجازهٔ دسترسی بدهید تا بتوانید آگاهی‌ها را ببینید. + کاربران دیگر در پیام‌های مستقیم و اتاق‌هایی که می‌پیوندید قادر خواهند بود سیاهه‌ای کامل از نشست‌هایتان را ببینند. +\n +\nاین کار مطمئنشان می‌کند که دارند واقعاً با شما صحبت می‌کنند؛ ولی همچنین به این معنیست که می‌توانند نام نشست‌هایی که این‌جا وارد کرده‌اید را هم ببینند. + نشست‌های تأیید شده آن‌هاییند که پس از ورود عبارت عبورتان یا تأیید هویتتان با نشست تأیید شده‌ای دیگر، واردشان شده‌اید. +\n +\nیعنی تمامی کلیدهای لارم برای رمزگشایی پیام‌های رمزنگاشته‌تان را داشته و این تأیید را به دیگران می‌دهند که به این نشست اطمینان دارید. + نشست‌های تأیید شده به حسابتان وارد و با عبارت عبور امنتان یا تأیید متقابل تأیید شده‌اند. +\n +\nیعنی کلیدهای رمزنگاری پیام‌های پیشینتان را داشته و به دیگر کاربران این تأیید را می‌دهند که این نشست، خودتان هستید. + نشست‌های تأیید نشده نشست‌هاییند که به آن‌ها وارد شده‌اید، ولی تأیید متقبالشان نکرده‌اید. +\n +\nباید به طور خاص مطمئن شوید که این نشست‌ها را می‌شناسید؛ چرا که می‌توانند نشان‌دهندهٔ استفادهٔ تأییدنشده از حسابتان باشند. + نشست‌های غیرفعّال نشست‌هاییند که مدّتیست استفاده نکرده‌اید، ولی به دریافت کلیدهای رمزنگاری ادامه می‌دهند. +\n +\nبرداشتن نشست‌های غیرفعّال امنیت و کارایی را بهبود داده و تشخیص مشکوک بودن نشست‌های جدید را برایتان راحت‌تر می‌کند. + بازبینی برای اطمینان از امن بودن حسابتان + نسشت‌هایی تأیید نشده دارید \ No newline at end of file From 60554b08cb2dca761094165fc58e6f06021d5532 Mon Sep 17 00:00:00 2001 From: Glandos Date: Tue, 6 Dec 2022 08:21:34 +0000 Subject: [PATCH 017/246] Translated using Weblate (French) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- library/ui-strings/src/main/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 d74d3bac71..9b57b949a7 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2868,4 +2868,6 @@ Modification Affiche les conversations récentes dans le menu de partage du système Activer le partage direct + Vérifiez pour assurer la sécurité de votre compte + Vous avez des sessions non vérifiées \ No newline at end of file From 0e470f2e819e50a811033298e2467e86990391fe Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 12 Dec 2022 13:45:07 +0000 Subject: [PATCH 018/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 6 +++++- 1 file changed, 5 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 1dd2134b90..798c046e18 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2814,7 +2814,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze A kérés sikertelen. Hang közvetítés felvételéhez és a szoba idővonalára küldéséhez. Hang közvetítés engedélyezése (aktív fejlesztés alatt) - Pufferelés + Pufferelés… Hang közvetítés szüneteltetése Hang közvetítés lejátszása vagy lejátszás folytatása Hang közvetítés felvétel leállítása @@ -2866,4 +2866,8 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Idézet Válasz erre: %s Szerkesztés + Tekintsd át, hogy meggyőződj arról, hogy a fiókod biztonságban van + Ellenőrizetlen bejelentkezéseid vannak + Friss beszélgetések megjelenítése a rendszer megosztó menüjében + Közvetlen megosztás engedélyezése \ No newline at end of file From bc1dc3eab6cf0add5ea330052c9a180c82d2ae61 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 13 Dec 2022 08:33:10 +0000 Subject: [PATCH 019/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2560 of 2560 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 | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) 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 da4c474689..89b4ec5b0c 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -107,8 +107,8 @@ Tema Terang Tema Gelap Tema Hitam - Pemberitahuan Berisik - Pemberitahuan Tenteram + Pemberitahuan berisik + Pemberitahuan diam Laporan Gangguan Kirimkan Sticker Memuat… @@ -384,17 +384,17 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Satu atau beberapa ujian gagal, coba saran yang kami tawarkan. Satu atau beberapa ujian gagal, mohon kirim laporan kutu untuk kami selidiki. Pengaturan Sistem. - Pemberitahuan diperbolehkan dalam pengaturan sistem. + Pemberitahuan diaktifkan dalam pengaturan sistem. Notifikasi dinonaktifkan dalam pengaturan sistem. \nMohon periksa pengaturan sistem anda. Buka Pengaturan Pengaturan Akun. - Pemberitahuan diperbolehkan dalam pengaturan akun Anda. + Pemberitahuan diaktifkan dalam pengaturan akun Anda. Notifikasi dinonaktifkan dalam pengaturan akun anda. \nMohon periksa pengaturan akun anda. Perbolehkan Pengaturan Perangkat. - Pemberitahuan diperbolehkan untuk sesi ini. + Pemberitahuan diaktifkan untuk sesi ini. Notifikasi tidak diaktifkan pada sesi ini. \nMohon periksa pengaturan ${app_name}. Perbolehkan @@ -439,9 +439,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Selesai Anda yakin ingin keluar\? Pengaturan Pemberitahuan Lanjutan - Urgensi pemberitahuan lewat kejadian + Kepentingan pemberitahuan berdasarkan peristiwa Pengaturan Sesukanya. - Perhatikan bahwa sebagian jenis pesan tersetel diam (mengeluarkan pemberitahuan tanpa suara). + Perhatikan bahwa sebagian jenis pesan disetel diam (mengeluarkan pemberitahuan tanpa suara). Sebagian pemberitahuan dimatikan dalam pengaturan Anda. [%1$s] \nError ini di luar kendali ${app_name} dan menurut Google, error ini muncul ketika terlalu banyak aplikasi terdaftar dengan FCM pada perangkat tersebut. Error ini tidak seharusnya mempengaruhi pengguna biasa. @@ -1202,7 +1202,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Kode QR Tambah dengan kode QR Tautan disalin ke klipboard - Aktifkan geser untuk balas di linimasa + Aktifkan geser untuk balas di lini masa Cari Nama Nama atau ID (#contoh:matrix.org) Tampilkan direktori ruangan @@ -1218,7 +1218,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengompresi gambar… Mengirim file (%1$s / %2$s) Mengenkripsi file… - Tampilkan peristiwa tersembunyi di linimasa + Tampilkan peristiwa tersembunyi di lini masa Mengenkripsi gambar mini… Menunggu… Pesan Langsung @@ -1457,7 +1457,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda tidak memiliki izin untuk mengaktifkan enkripsi ujung ke ujung di ruangan ini. Aktifkan enkripsi ujung ke ujung… Editor pesan - Linimasa + Lini Masa Mengirim emote yang dicantum berwarna pelangi Mengirim pesan yang dicantum berwarna pelangi Sesi ini tidak dapat berbagi verifikasi ini dengan sesi Anda yang lain. @@ -2442,7 +2442,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Jangan tinggalkan apa pun Tinggalkan semuanya Hal-hal di space ini - Mainkan gambar beranimasi di linimasa ketika muncul + Mainkan gambar beranimasi di lini masa ketika muncul Mainkan gambar beranimasi secara otomatis dtk mnt @@ -2760,7 +2760,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Perangkat yang lain sudah masuk. Homeserver tidak mendukung masuk dengan kode QR. Permintaan gagal. - Memungkinkan untuk merekam dan mengirim siaran suara dalam linimasa ruangan. + Memungkinkan untuk merekam dan mengirim siaran suara dalam lini masa ruangan. Aktifkan siaran suara (dalam pengembangan aktif) Memuat… Jeda siaran suara @@ -2814,4 +2814,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Membalas ke %s Tampilkan obrolan terkini dalam menu pembagian sistem Aktifkan pembagian langsung + Periksa untuk memastikan akun Anda aman + Anda memilki sesi yang belum diverifikasi \ No newline at end of file From 9e52c15b8f21176d178931f7cf3000501495dbba Mon Sep 17 00:00:00 2001 From: random Date: Sat, 10 Dec 2022 17:33:01 +0000 Subject: [PATCH 020/246] Translated using Weblate (Italian) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- library/ui-strings/src/main/res/values-it/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 d6a7858ebc..959cf2c061 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2859,4 +2859,6 @@ Modifica Mostra chat recenti nel menu di condivisione di sistema Attiva condivisione diretta + Controlla per assicurarti che l\'account sia sicuro + Hai sessioni non verificate \ No newline at end of file From 1bc5f3675c3bc26749a4df8e4d346106cd8e5534 Mon Sep 17 00:00:00 2001 From: paboum Date: Tue, 6 Dec 2022 16:18:03 +0000 Subject: [PATCH 021/246] Translated using Weblate (Polish) Currently translated at 93.4% (2392 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- .../src/main/res/values-pl/strings.xml | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) 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 e615950931..97d5f70ae4 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -834,8 +834,8 @@ Importowanie kluczy E2E z pliku \"%1$s\". Informacje o stronach trzecich Już wyświetlasz ten pokój! - id_aplikacji: - klucz_push: + App ID: + Push Key: wyświetlana_nazwa_aplikacji: nazwa_sesji: Url: @@ -1370,7 +1370,7 @@ Twój administrator serwera zablokował domyślne szyfrowanie punkt-punkt (e2e) w pokojach prywatnych w Wiadomościach Bezpośrednich. Nie masz uprawnień żeby uaktywnić szyfrowanie w tym pokoju. Wiadomość bezpośrednia - Domyślnie w %1$s + Zwykły w %1$s Opuść Ustawienia Operacje administratora @@ -2757,8 +2757,8 @@ Wyloguj się z %1$d sesji Wyloguj się z %1$d sesji - - + + Wyloguj się Wybierz sesje @@ -2787,4 +2787,15 @@ Załączniki Naklejki Galeria + Coś poszło nie tak. Sprawdź swoje połączenie i spróbuj ponownie. + Cytowanie + Odpowiadanie %s + Edytowanie + Otwórz ekran narzędzi programisty + 🔒 Włączyłeś ograniczenie szyfrowania tylko dla zweryfikowanych sesji dla wszystkich pokojów w ustawieniach bezpieczeństwa. + Odznacz wszystko + Zaznacz wszystko + Rozumiem + Zwiń %s pokojów + Rozwiń %s pokojów \ No newline at end of file From 9de41f1495dc19ff6f87c7a05d028e61770ceb2b Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Mon, 12 Dec 2022 12:48:02 +0000 Subject: [PATCH 022/246] Translated using Weblate (Russian) Currently translated at 99.9% (2558 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 d99d0bf9f4..38b152ff50 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -2847,12 +2847,12 @@ Показать QR-код на этом устройстве Выберите «Сканировать QR-код» Начните с экрана входа - Выберите «Войти при помощи QR-кода» + Выберите «Войти по QR-коду» Начните с экрана входа Выберите «Показать QR-код» Зайдите в Настройки -> Безопасность и Приватность Откройте приложение с другого устройства - Домашний сервер не поддерживает вход при помощи QR-кода. + Домашний сервер не поддерживает вход по QR-коду. Вход был отменён с другого устройства. Этот QR-код не работает. Другое устройство должно войти в учётную запись. @@ -2867,7 +2867,7 @@ Безопасное соединение установлено Сканируйте QR-код снизу при помощи устройства, с которого вы вышли с учётной записи. Используйте устройство, с которого вы вошли в учётную запись, чтобы сканировать QR-код снизу: - Войти при помощи QR-кода + Войти по QR-коду Используйте камеру на этом устройстве, чтобы сканировать QR-код, отображённый на вашем другом устройстве: Сканировать QR-код 3 @@ -2889,7 +2889,7 @@ \n \nВы должны удостовериться, что узнаёте эти сессии, так как они могут быть несанкционированным входом в вашу учётную запись. Вы можете использовать это устройство для входа с телефона или веб-устройства при помощи QR-кода. Для этого есть два способа: - Войти при помощи QR-кода + Войти по QR-коду Собственные названия сессий помогут вам легче распознать свои девайсы. Выйти из %1$d сессии From 270b2b703b446e5fbeb77e2b028299616b8dd2b7 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Mon, 5 Dec 2022 13:47:32 +0000 Subject: [PATCH 023/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 f59073c5db..bc0d1b102e 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2924,4 +2924,6 @@ Úprava Zobraziť posledné konverzácie v systémovej ponuke zdieľania Povoliť priame zdieľanie + Skontrolujte, či je vaše konto bezpečné + Máte neoverené relácie \ No newline at end of file From 3747aa0dc8a7a17b201e4f89c5f316b26c4fee3b Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Thu, 8 Dec 2022 22:25:35 +0000 Subject: [PATCH 024/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2543 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- library/ui-strings/src/main/res/values-sq/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index 58214e8a22..7d172c9d1e 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2659,7 +2659,7 @@ \nKy shërbyes Home mund të mos jetë formësuar të shfaqë harta. Përfundimet do të jenë të dukshme pasi të ketë përfunduar pyetësori Kur bëhet ftesë në një dhomë të fshehtëzuar që ka historik ndarjesh me të tjerët, historiku i fshehtëzuar do të jetë i dukshëm. - + Ndal transmetim zanor Luani ose vazhdoni luajtje transmetimi zanor Ndal incizim transmetimi zanor @@ -2853,4 +2853,6 @@ Aktivizo MD të lënë për më vonë Tkurr pjella të %s Zgjero pjella të %s + Shqyrtojini, për të garantuar se llogaria juaj është e parrezik + Keni sesione të paverifikuar \ No newline at end of file From ced70456c7f8bedeb2d57c543dd8ff04cab59d29 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 12 Dec 2022 19:20:15 +0000 Subject: [PATCH 025/246] Translated using Weblate (Swedish) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- library/ui-strings/src/main/res/values-sv/strings.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml index 45cfe4338b..9a3b4aeef4 100644 --- a/library/ui-strings/src/main/res/values-sv/strings.xml +++ b/library/ui-strings/src/main/res/values-sv/strings.xml @@ -2804,7 +2804,7 @@ Använd din inloggade enhet för att skanna QR-koden nedan: Logga in med QR-kod Använd den här enhetens kamera för att skanna QR-koden på din andra enhet: - Buffrar + Buffrar… Pausa röstsändning Spela eller återuppta röstsändning Avsluta inspelning av röstsändning @@ -2866,4 +2866,8 @@ Citerar Besvarar %s Redigerar + Granska för att försäkra att ditt konto är säkert + Du har overifierade sessioner + Visa nyliga chattar i systemets delningsmeny + Aktivera direktdelning \ No newline at end of file From 250af5657c8b032b74e226d16be34fc0461bff8c Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 5 Dec 2022 19:55:19 +0000 Subject: [PATCH 026/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2560 of 2560 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 | 2 ++ 1 file changed, 2 insertions(+) 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 6a1c5355ab..e03d7b814f 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2980,4 +2980,6 @@ Редагування Показувати останні бесіди в системному меню загального доступу Увімкнути пряме поширення + Перегляньте їх, щоб переконатися, що ваш обліковий запис у безпеці + У вас є незвірені сеанси \ No newline at end of file From 30d0e9c33be36396367b138b829d30696d1cf9ee Mon Sep 17 00:00:00 2001 From: phardyle Date: Wed, 7 Dec 2022 08:33:32 +0000 Subject: [PATCH 027/246] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (2560 of 2560 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 | 2 ++ 1 file changed, 2 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 f619864733..454c89fe21 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 @@ -2812,4 +2812,6 @@ 回复给 启用直接分享 在系统分享菜单中显示最近聊天 + 复查以确保你的账户是安全的 + 你有未验证的会话 \ No newline at end of file From 4e0e39b0bdcfcb963f934c6a2f5d0ff048c1e1f4 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Tue, 6 Dec 2022 03:49:32 +0000 Subject: [PATCH 028/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2560 of 2560 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- library/ui-strings/src/main/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) 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 9a5439b2ae..380e368ffd 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 @@ -2812,4 +2812,6 @@ 正在編輯 在系統分享選單中顯示最近聊天 啟用直接分享 + 檢查以確保您的帳號安全 + 您有未驗證的工作階段 \ No newline at end of file From 297cc33456ab93ac915369b53f823cb61881f9bc Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 12 Dec 2022 19:18:44 +0000 Subject: [PATCH 029/246] Translated using Weblate (Swedish) Currently translated at 100.0% (83 of 83 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40105100.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40105100.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105100.txt b/fastlane/metadata/android/sv-SE/changelogs/40105100.txt new file mode 100644 index 0000000000..3c4b0f2297 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Ny implementering av fullskärmsläget för rik-textredigeraren och buggfixar. +Full ändringslogg: https://github.com/vector-im/element-android/releases From 5e1d3e6c8df68ac05b46802679bd0508914a32c4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 15 Dec 2022 12:09:27 +0100 Subject: [PATCH 030/246] Escape % --- tools/release/releaseScript.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index f91e11584c..2ae4bf11aa 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -263,7 +263,7 @@ else fi printf "\n================================================================================\n" -printf "Wait for the GitHub action https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%3Amain to build the 'main' branch.\n" +printf "Wait for the GitHub action https://github.com/vector-im/element-android/actions/workflows/build.yml?query=branch%%3Amain to build the 'main' branch.\n" read -p "After GHA is finished, please enter the artifact URL (for 'vector-gplay-release-unsigned'): " artifactUrl printf "\n================================================================================\n" From b3d578d6b831972c4aa7e6dd3a7429347a0e5bd0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 15 Dec 2022 12:44:40 +0100 Subject: [PATCH 031/246] Release script: Improve creation of the release on GitHub. --- tools/release/releaseScript.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index 2ae4bf11aa..8273914c88 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -190,6 +190,9 @@ yes | towncrier build --version "v${version}" printf "\n================================================================================\n" read -p "Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things. Do not commit your change. Press enter when it's done." +# Get the changes to use it to create the GitHub release +changelogUrlEncoded=`git diff CHANGES.md | grep ^+ | tail -n +2 | cut -c2- | jq -sRr @uri | sed s/\(/%28/g | sed s/\)/%29/g` + printf "\n================================================================================\n" printf "Committing...\n" git commit -a -m "Changelog for version ${version}" @@ -354,10 +357,15 @@ apkPath="${targetPath}/vector-gplay-arm64-v8a-release-signed.apk" adb -d install ${apkPath} read -p "Please run the APK on your phone to check that the upgrade went well (no init sync, etc.). Press enter when it's done." -# TODO Get the block to copy from towncrier earlier (be may be edited by the release manager)? -read -p "Create the release on gitHub from the tag https://github.com/vector-im/element-android/tags, copy paste the block from the file CHANGES.md. Press enter when it's done." -read -p "Add the 4 signed APKs to the GitHub release. They are located at ${targetPath}. Press enter when it's done." +printf "\n================================================================================\n" +githubCreateReleaseLink="https://github.com/vector-im/element-android/releases/new?tag=v${version}&title=Element%%20Android%%20v${version}&body=${changelogUrlEncoded}" +printf "Creating the release on gitHub.\n" +printf "Open this link: ${githubCreateReleaseLink}\n" +printf "Then\n" +printf " - click on the 'Generate releases notes' button\n" +printf " - Add the 4 signed APKs to the GitHub release. They are located at ${targetPath}\n" +read -p ". Press enter when it's done. " printf "\n================================================================================\n" printf "Message for the Android internal room:\n\n" From 155f2aa0cb09d7e0f25e938edbe4fdcf17b4e9e3 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Thu, 15 Dec 2022 09:48:13 +0000 Subject: [PATCH 032/246] Translated using Weblate (Czech) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 11 ++++++++++- 1 file changed, 10 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 63e8caca5d..2589c38537 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -441,7 +441,7 @@ Žádný Zrušit Přihlásit se se single sign-on - To není platná adresa Matrix serveru + Toto není platná adresa Matrix serveru Domovský server není dostupný na této adrese, zkontrolujte ji prosím Odstraňování problémů s oznámeními Řešit diagnostiku @@ -2926,4 +2926,13 @@ Povolit přímé sdílení Zkontrolujte, zda je váš účet v bezpečí Máte neověřené relace + Tato relace nepodporuje šifrování, takže ji nelze ověřit. +\n +\nPři použití této relace se nebudete moci účastnit místností, kde je šifrování povoleno. +\n +\nPro dosažení nejlepšího zabezpečení a soukromí se doporučuje používat klienty Matrix, které šifrování podporují. + Odhlásit se ze všech ostatních relací + Tato relace nepodporuje šifrování, a proto ji nelze ověřit. + Získejte nejnovější sestavení (poznámka: můžete mít potíže s přihlášením) + Noční sestavení \ No newline at end of file From 1101adf00119344564a8518a24246e2990e307f8 Mon Sep 17 00:00:00 2001 From: Vri Date: Wed, 14 Dec 2022 06:52:43 +0000 Subject: [PATCH 033/246] Translated using Weblate (German) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) 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 7dcae136b8..24a1477787 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2869,4 +2869,13 @@ Direktes Teilen aktivieren Überprüfe sie, um ein sicheres Konto gewährleisten zu können Du hast nicht verifizierte Sitzungen + Hol dir den neuesten Build (Achtung: Du kannst dich eventuell nicht anmelden) + Nightly-Build + Diese Sitzung unterstützt keine Verschlüsselung, weshalb sie nicht verifiziert werden kann. +\n +\nDu wirst dich mit dieser Sitzung nicht an Unterhaltungen in Räumen mit aktivierter Verschlüsselung beteiligen können. +\n +\nAus Sicherheits- und Datenschutzgründen, wird die Nutzung von verschlüsselungsfähigen Matrix-Anwendungen empfohlen. + Von allen anderen Sitzungen abmelden + Diese Sitzung unterstützt keine Verschlüsselung und kann deshalb nicht verifiziert werden. \ No newline at end of file From 903eda80f8b45239778fe5380e743191c2889a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 14 Dec 2022 22:42:27 +0000 Subject: [PATCH 034/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2557 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) 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 e82586d074..2c4d63433f 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2861,4 +2861,13 @@ Näita viimaseid vestlusi süsteemses jagamisvaates Tagamaks, et su konto on sinu kontrolli all, vaata andmed üle Sul on verifitseerimata sessioone + Igaöine arendusversioon + Kasuta viimast arendusversiooni (aga võib tekkida erinevaid vigu, sealhulgas sisselogimisega) + Seda sessiooni ei saa verifitseerida, sest seal puudub krüptimise tugi. + Logi välja kõikidest oma muudest sessioonidest + Seda sessiooni ei saa verifitseerida, sest seal puudub krüptimise tugi. +\n +\nSelle sessiooniga ei saa sa osaleda krüptitud jututubades. +\n +\nParima turvalisuse ja privaatsuse nimel palun kasuta selliseid Matrix\'i kliente, mis toetavad krüptimist. \ No newline at end of file From 4b801e5c90aa3bc23228c85ceab8dfc0ab161a0a Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 14 Dec 2022 00:12:07 +0000 Subject: [PATCH 035/246] Translated using Weblate (Persian) Currently translated at 100.0% (2565 of 2565 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 | 9 +++++++++ 1 file changed, 9 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 1d16e7d29f..608a3e4c9b 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2870,4 +2870,13 @@ \nبرداشتن نشست‌های غیرفعّال امنیت و کارایی را بهبود داده و تشخیص مشکوک بودن نشست‌های جدید را برایتان راحت‌تر می‌کند. بازبینی برای اطمینان از امن بودن حسابتان نسشت‌هایی تأیید نشده دارید + این نشست از رمزنگاری پشتیبانی نمی‌کند؛ پس نمی‌تواند تأیید شود. +\n +\nهنگام استفاده از اسن نشست نخواهید توانست در اتاق‌هایی که رمزنگاریشان به کار افتاده شرکت کنید. +\n +\nبرای بهترین امنیت و محرمانگی، پیشنهاد می‌شود از کارخواه‌های ماتریکس دارای رمزنگاری استفاده کنید. + خروج از تمامی نشست‌های دیگر + این نشست از رمزنگاری پشتیبانی نکرده و بنابراین نمی‌تواند تأیید شود. + رفتن به جدیدترین ساخت (نکته: ممکن است برای ورود به مشکل بخورید) + ساخت شبانه \ No newline at end of file From e4f7c383e04a35d83ac50ce0142a5bbba766884c Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 15 Dec 2022 07:24:16 +0000 Subject: [PATCH 036/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) 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 798c046e18..60e4510a2e 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2870,4 +2870,13 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Ellenőrizetlen bejelentkezéseid vannak Friss beszélgetések megjelenítése a rendszer megosztó menüjében Közvetlen megosztás engedélyezése + Szerezd be a napi összeállítást (megjegyzés: lehet, hogy problémáid lesznek a bejelentkezéssel) + Napi összeállítás + Ez a munkamenet nem támogatja a titkosítást, így nem lehet ellenőrizni sem. +\n +\nEzzel a munkamenettel nem tudsz részt venni olyan szobákban ahol a titkosítás be van kapcsolva. +\n +\nA biztonság és a adatbiztonsági okokból javasolt olyan Matrix kliens használata ami támogatja a titkosítást. + Kijelentkezés minden más munkamenetből + Ez a munkamenet nem támogatja a titkosítást, így nem lehet ellenőrizni sem. \ No newline at end of file From ed517d1fa6f8e2273fbed92082e0425fed79b73e Mon Sep 17 00:00:00 2001 From: Linerly Date: Thu, 15 Dec 2022 11:08:28 +0000 Subject: [PATCH 037/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- library/ui-strings/src/main/res/values-in/strings.xml | 11 ++++++++++- 1 file changed, 10 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 89b4ec5b0c..d52436c707 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2119,7 +2119,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Sebuah kesalahan terjadi ketika memindahkan panggilan Pindahkan Sambungkan - Konsultasikan dulu + Konsultasi dahulu %1$s Ketuk untuk kembali Panggilan aktif (%1$s) · @@ -2816,4 +2816,13 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Aktifkan pembagian langsung Periksa untuk memastikan akun Anda aman Anda memilki sesi yang belum diverifikasi + Sesi ini tidak mendukung enkripsi, jadi ini tidak dapat diverifikasi. +\n +\nAnda tidak akan dapat berpartisipasi dalam ruangan di mana enkripsi diaktifkan ketika menggunakan sesi ini. +\n +\nUntuk keamanan dan privasi yang terbaik, kami menyarankan untuk menggunakan klien Matrix yang mendukung enkripsi. + Keluarkan semua sesi lain + Sesi ini tidak mendukung enkripsi dan tidak dapat diverifikasi. + Dapatkan bangunan terkini (catatan: Anda mungkin memiliki masalah saat masuk) + Bangunan nightly \ No newline at end of file From d6450d2d883418d7f85e54e2442087ab6a8a191f Mon Sep 17 00:00:00 2001 From: Philip Goto Date: Thu, 15 Dec 2022 09:26:33 +0000 Subject: [PATCH 038/246] Translated using Weblate (Dutch) Currently translated at 98.8% (2536 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/nl/ --- .../src/main/res/values-nl/strings.xml | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) 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 c5616ed761..791b198193 100644 --- a/library/ui-strings/src/main/res/values-nl/strings.xml +++ b/library/ui-strings/src/main/res/values-nl/strings.xml @@ -47,7 +47,7 @@ \nKamers importeren Initiële synchronisatie: \nGesprekken worden geladen -\nAls je aan veel kamers deelneemt kan dit even duren +\nAls u aan veel kamers deelneemt kan dit even duren Initiële synchronisatie: \nUitgenodigde kamers worden geïmporteerd Initiële synchronisatie: @@ -73,12 +73,12 @@ %1$s heeft %2$s als kameradressen toegevoegd. - %1$s heeft %2$s als gespreksadres verwijderd. - %1$s heeft %2$s als gespreksadressen verwijderd. + %1$s heeft %2$s verwijderd als adres voor deze kamer. + %1$s heeft %2$s verwijderd als adressen voor deze kamer. - %1$s heeft %2$s als gespreksadres toegevoegd en %3$s verwijderd. - %1$s heeft het hoofdadres voor dit gesprek ingesteld op %2$s. - %1$s heeft het hoofdadres voor dit gesprek verwijderd. + %1$s heeft %2$s toegevoegd en %3$s verwijderd als adres voor deze kamer. + %1$s heeft %2$s ingesteld als het hoofdadres voor deze kamer. + %1$s heeft het hoofdadres van deze kamer verwijderd. %1$s heeft gasten de toegang tot dit gesprek verleend. %1$s heeft gasten de toegang tot het gesprek verhinderd. %1$s heeft eind-tot-eind-versleuteling ingeschakeld. @@ -787,7 +787,7 @@ Publiek Iedereen kan deelnemer worden van deze kamer Afspelen - Je hebt het hoofdadres voor dit gesprek verwijderd. + U heeft het hoofdadres van deze kamer verwijderd. Je hebt %1$s uitgenodigd. Reden: %2$s Jouw uitnodiging. Reden: %1$s Bericht verstuurd @@ -884,11 +884,11 @@ Kan stembericht niet opnemen Kan stembericht niet afspelen Je hebt gasten de toegang tot dit gesprek verleend. - Je hebt het hoofdadres voor dit gesprek ingesteld op %1$s. - Je hebt %1$s als gespreksadres toegevoegd en %2$s verwijderd. + U heeft %1$s ingesteld als hoofdadres van deze kamer. + U heeft %1$s toegevoegd en %2$s verwijderd als adressen voor deze kamer. - Je hebt %1$s als gespreksadres verwijderd. - Je hebt %1$s als gespreksadressen verwijderd. + U heeft %1$s verwijderd als adres voor deze kamer. + U heeft %1$s verwijderd als adressen voor deze kamer. Je hebt %1$s als kameradres toegevoegd. @@ -2836,4 +2836,10 @@ %1$d geselecteerd %1$d geselecteerd + Nightly-versie + Quoten + Reageren op %s + Bewerking + Recente gesprekken in het deelmenu van het systeem tonen + Direct delen inschakelen \ No newline at end of file From 689e84055a6510cb9e715e1525c9d191f336cfd4 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Wed, 14 Dec 2022 00:16:09 +0000 Subject: [PATCH 039/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- .../ui-strings/src/main/res/values-pt-rBR/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 62cdb134d6..753a752e48 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 @@ -2868,4 +2868,15 @@ Editando Mostrar chats recentes no menu de compartilhar do sistema Habilitar compartilhar direto + Esta sessão não suporta encriptação, então ela não pode ser verificada. +\n +\nVocê não vai ser capaz de participar em salas onde encriptação está habilitada quando usando esta sessão. +\n +\nPara a melhor segurança e privacidade, é recomendado usar cliente Matrix que suportam encriptação. + Fazer signout de todas as outras sessões + Esta sessão não suporta encriptação e assim não pode ser verificada. + Revise para assegurar que sua conta está segura + Você tem sessões não-verificadas + Obtenha a build mais recente (note: você pode ter problema para fazer signin) + Build nightly \ No newline at end of file From 70e9adcd6c75608114cb6ea602b2b862c4ca4ad5 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Wed, 14 Dec 2022 09:30:49 +0000 Subject: [PATCH 040/246] Translated using Weblate (Russian) Currently translated at 99.8% (2561 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 38b152ff50..269e304e9d 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -2965,4 +2965,7 @@ Редактирование Показывать последние беседы в системном меню распостранения Включить прямое распостранение + Выйти из всех других сеансов + У вас есть незаверенные сеансы + Ночная сборка \ No newline at end of file From 0affe79a8666f739891a2969552b78a3c33e58d5 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 13 Dec 2022 21:09:44 +0000 Subject: [PATCH 041/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) 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 bc0d1b102e..7e1be8db49 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2926,4 +2926,13 @@ Povoliť priame zdieľanie Skontrolujte, či je vaše konto bezpečné Máte neoverené relácie + Táto relácia nepodporuje šifrovanie, takže ju nemožno overiť. +\n +\nPri používaní tejto relácie sa nebudete môcť zúčastňovať konverzácií v miestnostiach, kde je zapnuté šifrovanie. +\n +\nNa dosiahnutie čo najlepšieho zabezpečenia a súkromia sa odporúča používať Matrix klientov, ktoré podporujú šifrovanie. + Odhlásiť zo všetkých ostatných relácií + Táto relácia nepodporuje šifrovanie, a preto ju nemožno overiť. + Získajte najnovšiu zostavu (poznámka: môžete mať problémy s prihlásením) + Nočná zostava \ No newline at end of file From d46cb63dbad4c1ea78057b668fa50d3dbf16c345 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 14 Dec 2022 20:02:25 +0000 Subject: [PATCH 042/246] Translated using Weblate (Swedish) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- library/ui-strings/src/main/res/values-sv/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml index 9a3b4aeef4..1bf78ccf54 100644 --- a/library/ui-strings/src/main/res/values-sv/strings.xml +++ b/library/ui-strings/src/main/res/values-sv/strings.xml @@ -2870,4 +2870,13 @@ Du har overifierade sessioner Visa nyliga chattar i systemets delningsmeny Aktivera direktdelning + Den här sessioner stöder inte kryptering, så den kan inte verifieras. +\n +\nDu kommer inte kunna delta i rum där kryptering är aktiverat när du använder den här sessionen. +\n +\nFör bäst säkerhet och sekretess så rekommenderas det att använda Matrix-klienter som stöder kryptering. + Logga ut alla andra sessioner + Den här sessioner stöder inte kryptering och kan därför inte verifieras. + Hämta det senaste bygget (obs: du kan ha problem med att logga in) + Nightly-bygge \ No newline at end of file From 57cbd3a2af3b488133a99e6f1957bf15a9c38934 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 13 Dec 2022 22:53:08 +0000 Subject: [PATCH 043/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2565 of 2565 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 | 9 +++++++++ 1 file changed, 9 insertions(+) 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 e03d7b814f..c66f53c49f 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2982,4 +2982,13 @@ Увімкнути пряме поширення Перегляньте їх, щоб переконатися, що ваш обліковий запис у безпеці У вас є незвірені сеанси + Цей сеанс не підтримує шифрування, тому його неможливо звірити. +\n +\nПід час користування цим сеансом ви не зможете брати участь у кімнатах, в яких увімкнено шифрування. +\n +\nДля кращої безпеки й приватності радимо використовувати клієнти Matrix, які підтримують шифрування. + Вийти з усіх інших сеансів + Цей сеанс не підтримує шифрування і тому не може бути звірений. + Отримати найновішу збірку (примітка: у вас можуть виникнути проблеми з входом в систему) + Збірка Nightly \ No newline at end of file From 637f76ac9a8767ff598d959d261c0c3bcaa9ad3c Mon Sep 17 00:00:00 2001 From: phardyle Date: Thu, 15 Dec 2022 00:48:24 +0000 Subject: [PATCH 044/246] Translated using Weblate (Chinese (Simplified)) Currently translated at 99.9% (2563 of 2565 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 | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) 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 454c89fe21..b07c662ab4 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 @@ -1328,7 +1328,7 @@ 在此用户信任此会话之前,发送到该会话和从该会话发送的消息均标有警告。或者,你可以手动进行验证。 初始化交叉签名 重置密钥 - 二维码 + QR码 快要完成了!%s 显示对勾了吗? @@ -1656,7 +1656,7 @@ 你没有权限发起会议通话 重置 允许访问你的联系人。 - 如需扫描二维码,你须允许相机访问权限。 + 如需扫描QR码,你须允许相机访问权限。 没有更多结果 开始聊天 删除地址 \"%1$s\"? @@ -1713,8 +1713,8 @@ 发送电子邮件和电话号码 建议 已知用户 - 二维码 - 通过二维码添加 + QR码 + 通过QR码添加 房间设置 话题 房间话题(可选) @@ -1804,7 +1804,7 @@ %d 个条目 - 这不是有效的 Matrix 二维码 + 这不是有效的 Matrix QR码 扫描二维码 添加人员 邀请朋友 @@ -1943,8 +1943,8 @@ %1$s 拒绝了此通话 有未保存的更改。要放弃更改吗? 房间尚未创建。取消创建房间? - 未扫描二维码! - 无效的二维码(无效的标识)! + 未扫描QR码! + 无效的QR码(无效的标识)! 无法向你自己发送私聊消息! 通过文字共享 更改你当前的 PIN @@ -2539,7 +2539,7 @@ 自动允许 Element 通话小部件并授予相机/麦克风访问权限 启用 Element 通话权限快捷方式 实时位置 - 此二维码看起来格式不正确。请尝试使用其它方法进行验证。 + 此QR码看起来格式不正确。请尝试使用其它方法进行验证。 你无法访问加密消息历史。重置你的安全消息备份和验证密钥以重新开始。 无法验证此设备 你的服务器地址是什么? @@ -2655,8 +2655,8 @@ \n \n删除闲置会话可以提高安全性和性能,并使你更容易识别新会话是否可疑。 闲置会话 - 你可以使用此设备通过二维码登录移动设备或网络设备。 有两种方法可以做到这一点: - 使用二维码登录 + 你可以使用此设备通过QR码登录移动设备或网络设备。 有两种方法可以做到这一点: + 使用QR码登录 请注意,与你交流的人也可以看到会话名称。 自定义会话名称可以帮助你更轻松地识别你的设备。 重命名会话 @@ -2708,19 +2708,19 @@ 不匹配? 登录 连接到设备 - 扫描二维码 + 扫描QR码 登录移动设备? - 在此设备中显示二维码 - 选择“扫描二维码” + 在此设备中显示QR码 + 选择“扫描QR码” 从登录屏幕开始 - 选择“使用二维码登录” + 选择“使用QR码登录” 从登录屏幕开始 - 选择“显示二维码” + 选择“显示QR码” 转到设置 -> 安全和隐私 在你的其它设备上打开应用程序 - 主服务器不支持二维码登录。 + 主服务器不支持QR码登录。 登录已在另一台设备上取消。 - 该二维码无效。 + 该QR码无效。 另一台设备必须登录。 另一台设备已登录。 链接未在规定时间内完成。 @@ -2731,11 +2731,11 @@ 连接不成功 检查你已登录的设备,应显示以下代码。 确认以下代码与该设备匹配: 已建立安全连接 - 使用已退出登录的设备扫描下方二维码。 - 使用你已登录的设备扫描下方二维码: - 使用二维码登录 - 使用此设备上的相机扫描其它设备上显示的二维码: - 扫描二维码 + 使用已退出登录的设备扫描下方QR码。 + 使用你已登录的设备扫描下方QR码: + 使用QR码登录 + 使用此设备上的相机扫描其它设备上显示的QR码: + 扫描QR码 3 2 1 @@ -2762,7 +2762,7 @@ 停止语音广播录制 暂停语音广播录制 继续语音广播录制 - 扫描二维码 + 扫描QR码 语音广播 已启用: 会话ID: @@ -2814,4 +2814,7 @@ 在系统分享菜单中显示最近聊天 复查以确保你的账户是安全的 你有未验证的会话 + 登出全部其他会话 + 这个会话不支持加密,因此不能被验证。 + 获取最新构建(注意:你可能在登录时遇到麻烦) \ No newline at end of file From d0ddba9c4f8298d8d7325dbd38a20b074f1e3306 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 14 Dec 2022 01:32:06 +0000 Subject: [PATCH 045/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2565 of 2565 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- .../ui-strings/src/main/res/values-zh-rTW/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) 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 380e368ffd..01e6a21f57 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 @@ -2814,4 +2814,13 @@ 啟用直接分享 檢查以確保您的帳號安全 您有未驗證的工作階段 + 此工作階段不支援加密,因此無法驗證。 +\n +\n使用此工作階段時,您將無法參與啟用了加密的聊天室。 +\n +\n為了取得最佳的安全性與隱私,建議使用支援加密的 Matrix 客戶端。 + 登出其他所有工作階段 + 此工作階段不支援加密,因此無法驗證。 + 取得最新版本(注意:您可能會無法登入) + Nightly 版本 \ No newline at end of file From 09488d37412b9c48fa277a93bac2bedebcd08481 Mon Sep 17 00:00:00 2001 From: Vri Date: Wed, 14 Dec 2022 06:51:38 +0000 Subject: [PATCH 046/246] Translated using Weblate (German) Currently translated at 100.0% (84 of 84 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/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105110.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40105110.txt b/fastlane/metadata/android/de-DE/changelogs/40105110.txt new file mode 100644 index 0000000000..de5f4d90e8 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Der Vollbildmodus des Textverarbeitungseditors wurde neu umgesetzt und es wurden diverse Fehler behoben. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From 3fea73585c77ed9e4faa65f7b849f466fcdf1f57 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Wed, 14 Dec 2022 00:16:21 +0000 Subject: [PATCH 047/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (84 of 84 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/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40105110.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40105110.txt b/fastlane/metadata/android/pt-BR/changelogs/40105110.txt new file mode 100644 index 0000000000..c03bb2b140 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Nova implementação do modo de tela cheia para o Editor de Texto Rico e consertos de bugs. +Changelog completo: https://github.com/vector-im/element-android/releases From 0466d8a3274be79a525dc74a41f5ed70d8a4bea1 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 13 Dec 2022 21:03:24 +0000 Subject: [PATCH 048/246] Translated using Weblate (Slovak) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40105110.txt diff --git a/fastlane/metadata/android/sk/changelogs/40105110.txt b/fastlane/metadata/android/sk/changelogs/40105110.txt new file mode 100644 index 0000000000..af32da6d29 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Nová implementácia režimu celej obrazovky pre rozšírený textový editor a opravy chýb. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From b12b108ade003e30d48c97173e12036a59d129b9 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 14 Dec 2022 19:59:00 +0000 Subject: [PATCH 049/246] Translated using Weblate (Swedish) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40105110.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105110.txt b/fastlane/metadata/android/sv-SE/changelogs/40105110.txt new file mode 100644 index 0000000000..3c4b0f2297 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Ny implementering av fullskärmsläget för rik-textredigeraren och buggfixar. +Full ändringslogg: https://github.com/vector-im/element-android/releases From 8e661c308fffffa64dcc25f8394b0902b96ce76d Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 13 Dec 2022 22:50:21 +0000 Subject: [PATCH 050/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40105110.txt diff --git a/fastlane/metadata/android/uk/changelogs/40105110.txt b/fastlane/metadata/android/uk/changelogs/40105110.txt new file mode 100644 index 0000000000..5f348b8a50 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Нова реалізація повноекранного режиму для редактора розширеного тексту й виправлення помилок. +Перелік усіх змін: https://github.com/vector-im/element-android/releases From 438a3437501bd5a698c186c1d1b967d86e57e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 14 Dec 2022 22:40:23 +0000 Subject: [PATCH 051/246] Translated using Weblate (Estonian) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40105110.txt diff --git a/fastlane/metadata/android/et/changelogs/40105110.txt b/fastlane/metadata/android/et/changelogs/40105110.txt new file mode 100644 index 0000000000..833a567ce2 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: tekstitoimeti täisekraanivaate uus versioon ja erinevate vigade parandused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From cbcf4bddf8ce520bb0600c171ed04726d5becd24 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 14 Dec 2022 00:07:48 +0000 Subject: [PATCH 052/246] Translated using Weblate (Persian) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105110.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105110.txt b/fastlane/metadata/android/fa/changelogs/40105110.txt new file mode 100644 index 0000000000..b6a96e2fe8 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105110.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: پیاده‌سازی جدید حالت تمام‌صفحه برای ویرایشگر متن غنی و رفع اشکال‌ها. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 5a0c2c59a03d4deb5294f74df8b638bec68d0093 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 14 Dec 2022 01:28:48 +0000 Subject: [PATCH 053/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (84 of 84 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/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105110.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105110.txt b/fastlane/metadata/android/zh-TW/changelogs/40105110.txt new file mode 100644 index 0000000000..20341b84fe --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105110.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:格式化文字編輯器的全螢幕模式新實作與臭蟲修復。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From 1122385a60b936fa4a4f91606f9ecd5467892a5c Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 14 Dec 2022 06:28:19 +0000 Subject: [PATCH 054/246] Translated using Weblate (Czech) Currently translated at 100.0% (84 of 84 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/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105110.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105110.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105110.txt new file mode 100644 index 0000000000..8c51742e06 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Nová implementace celoobrazovkového režimu pro editor formátovaného textu a opravy chyb. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From 6acc324a2aa421c9113f4983a3a2612ed2ce246c Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 13 Dec 2022 23:48:00 +0000 Subject: [PATCH 055/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (84 of 84 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40105110.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40105110.txt diff --git a/fastlane/metadata/android/id/changelogs/40105110.txt b/fastlane/metadata/android/id/changelogs/40105110.txt new file mode 100644 index 0000000000..0c7d2f5262 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Penerapan baru mode layar penuh untuk Penyunting Teks Kaya dan perbaikan kutu. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From 95e9d305d1fdef68c007655091540a878c8ed505 Mon Sep 17 00:00:00 2001 From: Nidi Date: Sat, 17 Dec 2022 13:16:15 +0000 Subject: [PATCH 056/246] Translated using Weblate (Azerbaijani) Currently translated at 8.5% (219 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/az/ --- .../src/main/res/values-az/strings.xml | 113 +++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-az/strings.xml b/library/ui-strings/src/main/res/values-az/strings.xml index d5ab0adcb3..b8341cd2b4 100644 --- a/library/ui-strings/src/main/res/values-az/strings.xml +++ b/library/ui-strings/src/main/res/values-az/strings.xml @@ -35,7 +35,7 @@ ** Şifrəni aça bilmir: %s ** Göndərənin cihazı bu mesaj üçün açarları bizə göndərməyib. Mesaj göndərmək olmur - Matris xətası + Matrix xətası Şifrəli mesaj Elektron poçt ünvanı Telefon nömrəsi @@ -145,4 +145,115 @@ video göndərdi. stiker göndərdi. sorğu yaratdı. + Digər cihazda giriş ləğv edildi. + Ev serveri QR kodu ilə daxil olmağı dəstəkləmir. + Tətbiqi digər cihazınızda açın + Tənzimləmələr -> Təhlükəsizlik & Məxfilik bölməsinə keç + \'QR kodunu göstər\' seç + Giriş ekranında başlat + \'QR kodu ilə daxil ol\' seç + Giriş ekranında başlat + \'QR kodunu skan et\' seç + QR kodunu bu cihazda göstər + Mobil cihazda daxil olursunuz\? + QR kodunu skan et + Cihaza qoşulur + Daxil olursunuz + Uyğunluq yoxdur\? + Bir daha cəhd et + Təsdiqlə + Bu kodun mənbəyini bildiyinizə əmin olun. Cihazları əlaqələndirməklə siz kiməsə hesabınıza tam giriş imkanı təmin edəcəksiniz. + Qalın format tətbiq et + Kursiv formatını tətbiq et + Alt xətt formatını tətbiq et + Bu otaq üçün əsas ünvanı sildiniz. + %1$s, %2$s əlavə etdi və %3$s-nı bu otaq üçün ünvan kimi sildi. + + Bu otaq üçün ünvan kimi %1$s-nı sildiniz. + Bu otaq üçün ünvan kimi %1$s-nı sildiniz. + + + %1$s, bu otaq üçün %2$s ünvanını sildi. + %1$s, bu otaq üçün %2$s ünvanını sildi. + + + Bu otaq üçün ünvan olaraq %1$s əlavə etdiniz. + Bu otaq üçün ünvan olaraq %1$s əlavə etdiniz. + + + %1$s, bu otaq üçün %2$s ünvanını əlavə etdi. + %1$s, bu otaq üçün %2$s ünvanını əlavə etdi. + + %1$s-ın⁴ dəvətini geri götürdünüz. Səbəb: %2$s + %1$s üçün dəvəti qəbul etdiniz. Səbəb: %2$s + %1$s-ı qadağan etdiniz. Səbəb: %2$s + Siz %1$s qadağanını sildiniz. Səbəb: %2$s + %1$s-ı sildiniz. Səbəb: %2$s + Siz dəvəti rədd etdiniz. Səbəb: %1$s + Siz getdiniz. Səbəb: %1$s + %1$s tərk etdi. Səbəb: %2$s + Otağı tərk etdiniz. Səbəb: %1$s + Siz qoşuldunuz. Əsas: %1$s + %1$s qoşuldu. Əsas: %2$s + Otağa qoşuldunuz. Əsas: %1$s + %1$s-ı dəvət etdiniz. Əsas: %2$s + Sizin dəvətiniz. Əsas: %1$s + Mesaj göndərildi + - Bəzi istifadəçilər nəzərə alınmayıb + ${app_name} aşağıdakı səbəbə görə: +\n%s +\n +\nGüncəl olmaq üçün təmiz keşi yerinə yetirməlidir. +\nNəzərə alın ki, bu əməliyyat tətbiqi yenidən işə salacaq və bir az vaxt apara bilər. + İlkin sinxronizasiya sorğusu + İlkin sinxronizasiya: +\nMəlumat endirilir… + İlkin sinxronizasiya: +\n Server cavabı gözlənilir… + Boş otaq (%s idi) + + %1$s, %2$s, %3$s və digər %4$d + %1$s, %2$s, %3$s və digər %4$d + + %1$s, %2$s, %3$s və %4$s + %1$s, %2$s və %3$s + Bu otağa qoşulmağa icazəniz yoxdur + %s uşağı yay + %s uşağı yığışdır + Otaqları Araşdır + Yeri Dəyiş + Otaq Yarat + Söhbət Başlat + Bütün Söhbətlər + Səsli yayımı bitirdiniz. + %1$s səsli yayımı bitirdi. + %1$s, %2$s - %3$s + %1$s, %2$s üçün güc səviyyəsini dəyişdi. + Siz %1$s üçün güc səviyyəsini dəyişdirdiniz. + Xüsusi + Fərdi (%1$d) + Defolt + Münsif + Müdir + %1$s vidcetini dəyişdirdiniz + %1$s, %2$s vidcetini dəyişdirdi + %1$s vidcetini sildiniz + %1$s, %2$s vidcetini sildi + %1$s vidceti əlavə etdiniz + %1$s, %2$s vidceti əlavə etdi + %1$s üçün dəvəti qəbul etdiniz + %1$s üçün dəvəti ləğv etdiniz + %1$s, %2$s üçün dəvəti ləğv etdi + • IP literallarına uyğunlaşan serverlər indi qadağan edilib. + • IP literalları uyğunlaşan serverlərə indi icazə verilir. + • %s ilə uyğunlaşan serverlər icazə verilən siyahıdan təmizləndi. + • %s ilə uyğunlaşan serverlərə indi icazə verilir. + • %s ilə uyğunlaşan serverlər qadağa siyahısından təmizləndi. + • %s ilə uyğunlaşan serverlər indi qadağan edilib. + + %d server ACLs dəyişiklik + %d server ACLs dəyişiklik + + • IP literallarına uyğunlaşan serverlər qadağan edildi. + • IP literallarına uyğunlaşan serverlərə icazə verilir. \ No newline at end of file From 3429c3ef346bd997983d9bb22e834feb5514c569 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Fri, 16 Dec 2022 11:08:15 +0000 Subject: [PATCH 057/246] Translated using Weblate (Czech) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 2589c38537..4df730f8cc 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2935,4 +2935,7 @@ Tato relace nepodporuje šifrování, a proto ji nelze ověřit. Získejte nejnovější sestavení (poznámka: můžete mít potíže s přihlášením) Noční sestavení + Živé vysílání + Ukončili jste hlasové vysílání. + %1$s ukončil(a) hlasové vysílání. \ No newline at end of file From 33663866801ad35d3365319134cc1990504639eb Mon Sep 17 00:00:00 2001 From: Vri Date: Sat, 17 Dec 2022 13:00:55 +0000 Subject: [PATCH 058/246] Translated using Weblate (German) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 24a1477787..588c6e93f0 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2878,4 +2878,7 @@ \nAus Sicherheits- und Datenschutzgründen, wird die Nutzung von verschlüsselungsfähigen Matrix-Anwendungen empfohlen. Von allen anderen Sitzungen abmelden Diese Sitzung unterstützt keine Verschlüsselung und kann deshalb nicht verifiziert werden. + Echtzeit-Übertragung + Du hast eine Sprachübertragung beendet. + %1$s beendete eine Sprachübertragung. \ No newline at end of file From 3da0bf788b49d353ad566af5323e24dab9e4be3f Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Fri, 16 Dec 2022 08:28:51 +0000 Subject: [PATCH 059/246] Translated using Weblate (Persian) Currently translated at 100.0% (2568 of 2568 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 | 3 +++ 1 file changed, 3 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 608a3e4c9b..eb5cf384dd 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2879,4 +2879,7 @@ این نشست از رمزنگاری پشتیبانی نکرده و بنابراین نمی‌تواند تأیید شود. رفتن به جدیدترین ساخت (نکته: ممکن است برای ورود به مشکل بخورید) ساخت شبانه + پخش زنده + به پخش صوتی پایان دادید. + %1$s به پخش صوتی پایان داد. \ No newline at end of file From f035eaa76ed8edeca10970a82f11b7a2ce9151c2 Mon Sep 17 00:00:00 2001 From: Glandos Date: Fri, 16 Dec 2022 08:28:37 +0000 Subject: [PATCH 060/246] Translated using Weblate (French) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- .../ui-strings/src/main/res/values-fr/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 9b57b949a7..e659e2f416 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2870,4 +2870,16 @@ Activer le partage direct Vérifiez pour assurer la sécurité de votre compte Vous avez des sessions non vérifiées + Cette session ne prend pas en charge le chiffrement, elle ne peut donc pas être vérifiée. +\n +\nVous ne pourrez pas participer dans les salons où le chiffrement est activé en utilisant cette session. +\n +\nPour de meilleures sécurité et confidentialité, il est recommandé d’utiliser des clients Matrix qui prennent en charge le chiffrement. + Déconnecter toutes les autres sessions + Cette session ne prend pas en charge le chiffrement, elle ne peut donc pas être vérifiée. + Diffusion en direct + Obtenir la toute dernière version (note : vous pourriez avoir des problèmes pour vous connecter) + Version Nightly + Vous avez terminé une diffusion audio. + %1$s a terminé une diffusion audio. \ No newline at end of file From 8310f4619af0e4fef3116f13ed70b301faef5170 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 16 Dec 2022 07:49:54 +0000 Subject: [PATCH 061/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 60e4510a2e..ab21ea3b92 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2879,4 +2879,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze \nA biztonság és a adatbiztonsági okokból javasolt olyan Matrix kliens használata ami támogatja a titkosítást. Kijelentkezés minden más munkamenetből Ez a munkamenet nem támogatja a titkosítást, így nem lehet ellenőrizni sem. + Élő közvetítés + A hang közvetítést befejezted. + %1$s befejezte a hang közvetítést. \ No newline at end of file From abbfc1da84359b63cb633b305da06446670ec08c Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 17 Dec 2022 10:10:34 +0000 Subject: [PATCH 062/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- library/ui-strings/src/main/res/values-in/strings.xml | 5 ++++- 1 file changed, 4 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 d52436c707..c7d633846a 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2314,7 +2314,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Gagal untuk memuat peta Peta Catatan: aplikasi akan dimulai ulang - Aktifkan Pesan Utasan + Aktifkan pesan utasan Hubungkan ke server Ingin bergabung ke server yang sudah ada\? Lewati pertanyaan ini @@ -2825,4 +2825,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Sesi ini tidak mendukung enkripsi dan tidak dapat diverifikasi. Dapatkan bangunan terkini (catatan: Anda mungkin memiliki masalah saat masuk) Bangunan nightly + Siaran langsung + Anda mengakhiri sebuah siaran suara. + %1$s mengakhiri sebuah siaran suara. \ No newline at end of file From c99459e07b54a08bec24e50fafe4cf42cdb9fa3a Mon Sep 17 00:00:00 2001 From: random Date: Fri, 16 Dec 2022 14:12:21 +0000 Subject: [PATCH 063/246] Translated using Weblate (Italian) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- .../ui-strings/src/main/res/values-it/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 959cf2c061..211ea642e4 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2861,4 +2861,16 @@ Attiva condivisione diretta Controlla per assicurarti che l\'account sia sicuro Hai sessioni non verificate + Questa sessione non supporta la crittografia, perciò non può essere verificata. +\n +\nNon potrai partecipare in stanze dove la crittografia è attiva mentre usi questa sessione. +\n +\nPer maggiore sicurezza e privacy, è consigliabile usare i client di Matrix che supportano la crittografia. + Disconnetti da tutte le altre sessioni + Questa sessione non supporta la crittografia, perciò non può essere verificata. + Trasmissione in diretta + Ottieni la build più recente (nota: potresti avere problemi nell\'accesso) + Nightly build + Hai terminato una trasmissione vocale. + %1$s ha terminato una trasmissione vocale. \ No newline at end of file From fb1cdc888c2159a4cc46150b99dd6ac70a71434a Mon Sep 17 00:00:00 2001 From: Kazevic Date: Sun, 18 Dec 2022 13:00:40 +0000 Subject: [PATCH 064/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.9% (2567 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- library/ui-strings/src/main/res/values-pt-rBR/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 753a752e48..e083da85f5 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 @@ -2879,4 +2879,7 @@ Você tem sessões não-verificadas Obtenha a build mais recente (note: você pode ter problema para fazer signin) Build nightly + Transmissão ao vivo + Você terminou uma transmissão de voz. + %1$s terminou uma transmissão de voz. \ No newline at end of file From f45ecaa0f706f3af4d3619ed9a64489c48861f45 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Fri, 16 Dec 2022 00:28:30 +0000 Subject: [PATCH 065/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 7e1be8db49..e49fcee9c7 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2935,4 +2935,7 @@ Táto relácia nepodporuje šifrovanie, a preto ju nemožno overiť. Získajte najnovšiu zostavu (poznámka: môžete mať problémy s prihlásením) Nočná zostava + Živé vysielanie + Ukončili ste hlasové vysielanie. + %1$s ukončil/a hlasové vysielanie. \ No newline at end of file From a267965ab5aa303105de05889539e0c82f85e99f Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 16 Dec 2022 19:07:47 +0000 Subject: [PATCH 066/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2551 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- .../ui-strings/src/main/res/values-sq/strings.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index 7d172c9d1e..119c948c5a 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2343,7 +2343,7 @@ S’u arrit të ngarkohej hartë Hartë Shënim: aplikacioni do të riniset - Aktivizoni Rrjedha Mesazhesh + Aktivizoni rrjedha mesazhesh Lidhu te shërbyesi Po shihni për të marrë pjesë në një shërbyes ekzistues\? anashkalojeni këtë pyetje @@ -2855,4 +2855,16 @@ Zgjero pjella të %s Shqyrtojini, për të garantuar se llogaria juaj është e parrezik Keni sesione të paverifikuar + Ky sesion nuk mbulon fshehtëzim, ndaj s’mund të verifikohet. +\n +\nS’do të jeni në gjendje të merrni pjesë në dhoma ku është i aktivizuar fshehtëzimi, kur përdorni këtë sesion. +\n +\nPër sigurinë dhe privatësinë më të mirë, rekomandohet të përdorni klientë Matrix që mbulojnë fshehtëzimin. + Dilni nga krejt sesionet e tjerë + Ky sesion nuk mbulon fshehtëzim dhe ndaj s’mund të verifikohet. + Transmetim i drejtpërdrejtë + Merrni montimin më të ri (shënim: mund të keni probleme të bëni hyrjen) + Montim i përnatshëm + Përfunduat një transmetim zanor. + %1$s përfundoi një transmetim zanor. \ No newline at end of file From 48adaa4060791347aefbcf75ab2d2b61fa24bdea Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 16 Dec 2022 01:22:52 +0000 Subject: [PATCH 067/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2568 of 2568 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 | 3 +++ 1 file changed, 3 insertions(+) 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 c66f53c49f..6ac7809199 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2991,4 +2991,7 @@ Цей сеанс не підтримує шифрування і тому не може бути звірений. Отримати найновішу збірку (примітка: у вас можуть виникнути проблеми з входом в систему) Збірка Nightly + Трансляція наживо + Ви завершили голосову трансляцію. + %1$s завершує голосову трансляцію. \ No newline at end of file From ac5f2fc2408a481c6a7926ee3e0d6ab6ac001734 Mon Sep 17 00:00:00 2001 From: phardyle Date: Fri, 16 Dec 2022 00:31:43 +0000 Subject: [PATCH 068/246] Translated using Weblate (Chinese (Simplified)) Currently translated at 99.9% (2566 of 2568 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 | 4 ++++ 1 file changed, 4 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 b07c662ab4..03663405c7 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 @@ -2817,4 +2817,8 @@ 登出全部其他会话 这个会话不支持加密,因此不能被验证。 获取最新构建(注意:你可能在登录时遇到麻烦) + 实时广播 + Nightly构建 + 你结束了一个语音广播。 + %1$s结束了一个语音广播。 \ No newline at end of file From 5887dce84341ce5a296cf74b8b937c9b201442bd Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 16 Dec 2022 02:27:30 +0000 Subject: [PATCH 069/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- library/ui-strings/src/main/res/values-zh-rTW/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 01e6a21f57..771d5adbeb 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 @@ -2823,4 +2823,7 @@ 此工作階段不支援加密,因此無法驗證。 取得最新版本(注意:您可能會無法登入) Nightly 版本 + 即時廣播 + 您結束了語音廣播。 + %1$s 結束了語音廣播。 \ No newline at end of file From 5de471d7a35f6525dc410372ae0a8b1a16ab3ffa Mon Sep 17 00:00:00 2001 From: Vri Date: Sat, 17 Dec 2022 12:52:20 +0000 Subject: [PATCH 070/246] Translated using Weblate (German) Currently translated at 100.0% (85 of 85 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/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105120.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40105120.txt b/fastlane/metadata/android/de-DE/changelogs/40105120.txt new file mode 100644 index 0000000000..901b4c2a70 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Threads sind nun automatisch aktiviert. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From e1f98c04d67b59346927f160bcd89bb6046d0b9c Mon Sep 17 00:00:00 2001 From: Glandos Date: Fri, 16 Dec 2022 08:23:32 +0000 Subject: [PATCH 071/246] Translated using Weblate (French) Currently translated at 100.0% (85 of 85 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/40105110.txt | 2 ++ fastlane/metadata/android/fr-FR/changelogs/40105120.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105110.txt create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105120.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105110.txt b/fastlane/metadata/android/fr-FR/changelogs/40105110.txt new file mode 100644 index 0000000000..9f0d0823b4 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Nouvelle implémentation du mode plein écran pour l’éditeur de texte formaté, et correction de bogues. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105120.txt b/fastlane/metadata/android/fr-FR/changelogs/40105120.txt new file mode 100644 index 0000000000..4101bb0c86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Fils de discussion activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases From 877dc93b0023789f3519e491d0ed717f760caae8 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Fri, 16 Dec 2022 00:27:04 +0000 Subject: [PATCH 072/246] Translated using Weblate (Slovak) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40105120.txt diff --git a/fastlane/metadata/android/sk/changelogs/40105120.txt b/fastlane/metadata/android/sk/changelogs/40105120.txt new file mode 100644 index 0000000000..d5b5ad330d --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna sú teraz predvolene zapnuté. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From e4f65f81412abbd129b6e003baa1fbdbf05322d7 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 16 Dec 2022 01:20:53 +0000 Subject: [PATCH 073/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40105120.txt diff --git a/fastlane/metadata/android/uk/changelogs/40105120.txt b/fastlane/metadata/android/uk/changelogs/40105120.txt new file mode 100644 index 0000000000..edbd209d17 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Гілки відтепер типово ввімкнено. +Перелік усіх змін: https://github.com/vector-im/element-android/releases From d80074fcda3a9d789921ca1f11b052d30983d2b5 Mon Sep 17 00:00:00 2001 From: random Date: Fri, 16 Dec 2022 14:13:15 +0000 Subject: [PATCH 074/246] Translated using Weblate (Italian) Currently translated at 100.0% (85 of 85 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/40105110.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/40105120.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40105110.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/40105120.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40105110.txt b/fastlane/metadata/android/it-IT/changelogs/40105110.txt new file mode 100644 index 0000000000..7dc50eab33 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: nuova implementazione della modalità a schermo intero per l'editor in Rich Text e correzione di errori. +Cronologia completa: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/it-IT/changelogs/40105120.txt b/fastlane/metadata/android/it-IT/changelogs/40105120.txt new file mode 100644 index 0000000000..ab24842e82 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: i messaggi in conversazioni sono attivi in modo predefinito. +Cronologia completa: https://github.com/vector-im/element-android/releases From 1ba4f59603e4f373dc735cc791deddf36042ea1f Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Fri, 16 Dec 2022 08:29:51 +0000 Subject: [PATCH 075/246] Translated using Weblate (Persian) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105120.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105120.txt b/fastlane/metadata/android/fa/changelogs/40105120.txt new file mode 100644 index 0000000000..0c3cc5aa31 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105120.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رشته‌ها اکنون به صورت پیش‌گزیده به کار افتاده‌اند. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 0ff8a14863053922392d21bc01cfae388d48302f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 16 Dec 2022 02:27:58 +0000 Subject: [PATCH 076/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (85 of 85 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/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105120.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105120.txt b/fastlane/metadata/android/zh-TW/changelogs/40105120.txt new file mode 100644 index 0000000000..9c66f3c2ad --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105120.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串現在預設啟用。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From 567c556b6850629c8de55d4d860f596dacb728a8 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Fri, 16 Dec 2022 11:09:05 +0000 Subject: [PATCH 077/246] Translated using Weblate (Czech) Currently translated at 100.0% (85 of 85 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/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105120.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105120.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105120.txt new file mode 100644 index 0000000000..b7f38f629f --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Vlákna jsou nyní ve výchozím nastavení povolena. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From a26cac730435240ea5d2629de02b8d5b86468ddc Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 17 Dec 2022 10:09:38 +0000 Subject: [PATCH 078/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40105120.txt diff --git a/fastlane/metadata/android/id/changelogs/40105120.txt b/fastlane/metadata/android/id/changelogs/40105120.txt new file mode 100644 index 0000000000..173a1bfb1b --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Utasan sekarang diaktifkan secara bawaan. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From bc77bf5fdee4ecb951d8690ca3735b8ef48ceff8 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 16 Dec 2022 19:11:08 +0000 Subject: [PATCH 079/246] Translated using Weblate (Albanian) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40105110.txt | 2 ++ fastlane/metadata/android/sq/changelogs/40105120.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/sq/changelogs/40105110.txt create mode 100644 fastlane/metadata/android/sq/changelogs/40105120.txt diff --git a/fastlane/metadata/android/sq/changelogs/40105110.txt b/fastlane/metadata/android/sq/changelogs/40105110.txt new file mode 100644 index 0000000000..78d3d9785b --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Sendërtim i ri i mënyrë “Sa krejt ekrani” për Përpunuesin Tekst i Pasur, si dhe ndreqje të metash. +Regjistër ndryshimesh: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sq/changelogs/40105120.txt b/fastlane/metadata/android/sq/changelogs/40105120.txt new file mode 100644 index 0000000000..51350f5c00 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Rrjedhat tanimë janë të aktivizuara, si parazgjedhje. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases From 787d1bb59c915a3839c66555220537de81515c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 19 Dec 2022 04:23:18 +0000 Subject: [PATCH 080/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2560 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 2c4d63433f..8ac7097699 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2870,4 +2870,7 @@ \nSelle sessiooniga ei saa sa osaleda krüptitud jututubades. \n \nParima turvalisuse ja privaatsuse nimel palun kasuta selliseid Matrix\'i kliente, mis toetavad krüptimist. + Ringhäälingukõne on eetris + Sa lõpetasid ringhäälingukõne. + %1$s lõpetas ringhäälingukõne. \ No newline at end of file From 6368ec446b166f9ac85b366cd3620d549df83369 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Mon, 19 Dec 2022 13:52:22 +0000 Subject: [PATCH 081/246] Translated using Weblate (Russian) Currently translated at 99.8% (2564 of 2568 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 | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 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 269e304e9d..26fc66816f 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -432,7 +432,7 @@ Сбросить основной адрес Ошибка дешифровки Публичное название - ID сессии + ID сеанса Ключ сессии Экспорт E2E ключей Экспорт ключей @@ -1186,7 +1186,7 @@ Режим разработчика активирует скрытые функции, а также может сделать приложение менее стабильным. Только для разработчиков! Настройки Текущая сессия - Другие сессии + Другие сеансы Включить шифрование Недоверенный вход Вложения @@ -1390,7 +1390,7 @@ Вы приняли Подтверждение отправлено Запрос на подтверждение - Заверьте эту сессию + Заверьте этот сеанс Сканируйте код с помощью устройства другого пользователя, чтобы безопасно проверить друг друга Сканировать их код Невозможно сканировать @@ -1443,14 +1443,14 @@ Активные сессии Показать все сессии Управление сессиями - Выйти из этой сессии + Выйти из этого сеанса Нет доступной криптографической информации %d сессия активна %d сессии активны %d сессий активно - Заверьте эту сессию + Заверьте этот сеанс Используйте существующую сессию для подтверждения этой, предоставив ей доступ к зашифрованным сообщениям. Инструменты для разработчиков Данные учётной записи @@ -2661,8 +2661,8 @@ Не удалось загрузить карту \nВозможно, этот домашний сервер не настроен для отображения карт. Все беседы - Для лучшей безопасности заверьте свои сессии и выйдите из тех, которые более не признаёте или не используете. - Другие сессии + Для лучшей защиты заверьте свои сеансы и выйдите из тех, которые более не признаёте или не используете. + Другие сеансы Сессии Создать беседу или комнату ЛС @@ -2680,35 +2680,35 @@ Создать комнату Посмотреть все (%1$d) Повысьте безопасность учётной записи, следуя этим рекомендациям. - Заверенная · Последняя активность %1$s - Незаверенная сессия - Заверенная сессия + Заверенный · Последняя активность %1$s + Незаверенный сеанс + Заверенный сеанс Неизвестный тип устройства Компьютер Мобильный - Незаверенная · Последняя активность %1$s + Незаверенный · Последняя активность %1$s Рекомендации по безопасности - Незаверенные сессии - Неактивные сессии + Незаверенные сеансы + Неактивные сеансы Добро пожаловать в ${app_name}, \n%s. Оставить отзыв - Название сессии + Название сеанса Неактивные IP-адрес Последняя активность - Сведения о сессии - Для лучшей безопасности выйдите из всех сессий, которые более не признаёте или не используете. + Сведения о сеансе + Для лучшей безопасности выйдите из всех сеансов, которые более не признаёте или не используете. Заверенные - Все сессии + Все сеансы Последняя активность %1$s Устройство - Сессия - Текущая сессия - Заверить сессию + Сеанс + Текущий сеанс + Заверить сеанс Подробности - Эта сессия готова к безопасному обмену сообщениями. - Текущая сессия готова к безопасному обмену сообщениями. + Этот сеанс готов к защищенной переписке. + Текущий сеанс готов к защищенной переписке. Веб-браузер Пространства — это новый способ организации комнат и людей. Создайте пространство, чтобы начать. Новый вид @@ -2722,18 +2722,18 @@ \nвыглядит слегка пустовато. Попробовать Информация о приложении, устройстве и активности. - Подтвердите текущую сессию для более безопасного обмена сообщениями. + Заверьте текущий сеанс для усиления защиты переписки. Пока нет пространств. Подтвердите свои сессии для более безопасного обмена сообщениями или выйдите из тех, которые более не признаёте или не используете. - Подтвердите или выйдите из незаверенных сессий. - Подтвердите или выйдите из этой сессии для лучшей безопасности и надёжности. + Заверьте или выйдите из незаверенных сеансов. + Заверьте или выйдите из этого сеанса для лучшей безопасности и надёжности. Ничего нового. Заверенных сессий не обнаружено. Незаверенных сессий не обнаружено. Неактивных сессий не обнаружено. Очистить фильтр - Не готовы к безопасному обмену сообщениями - Готовы к безопасному обмену сообщениями + Не готовы к защищенной переписке + Готовы к защищенной переписке Неактивны %1$d день или дольше Неактивны %1$d дня или дольше @@ -2742,17 +2742,17 @@ Незаверенные Фильтр - Незаверенная · Текущая сессия - Переименовать сессию - Название сессии + Незаверенный · Текущий сеанс + Переименовать сеанс + Название сеанса Заверенные - Выйти из этой сессии + Выйти из этого сеанса Неактивные Незаверенные - Пожалуйста, имейте в виду, что названия сессий также видны людям, с которыми вы общаетесь. - Заверенные сессии - Незаверенные сессии - Неактивные сессии + Пожалуйста, имейте в виду, что названия сеансов также видны людям, с которыми вы общаетесь. + Заверенные сеансы + Незаверенные сеансы + Неактивные сеансы Добавляет (╯°□°)╯︵ ┻━┻ в начало сообщения Приватная клавиатура Запрещает клавиатуре обновлять персональные данные, такие как история набора текста и словарь, на основе того, что вы набрали при общении. Обратите внимание, что некоторые клавиатуры могут не соблюдать эту настройку. @@ -2762,7 +2762,7 @@ Неактивные сессии — это сессии, которыми вы не пользовались определённое время, но они продолжают получать ключи шифрования. \n \nУдаление неактивных сессий повышает безопасность и производительность, а также облегчает выявление подозрительных новых сессий. - Переименование сессий + Переименование сеансов Другие пользователи в личных сообщениях и комнатах, к которым вы присоединились, могут просматривать весь список ваших сессий. \n \nЭто даёт им уверенность в том, что они действительно общаются с вами, но это также означает, что они могут видеть название сессии, которое вы ввели здесь. @@ -2968,4 +2968,12 @@ Выйти из всех других сеансов У вас есть незаверенные сеансы Ночная сборка + Этот сеанс не поддерживает шифрование, поэтому его невозможно заверить. +\n +\nПри использовании этого сеанса вы не сможете участвовать в комнатах, где включено шифрование. +\n +\nДля лучшей защиты и приватности рекомендуется использовать клиенты Matrix, поддерживающие шифрование. + Этот сеанс не поддерживает шифрование и поэтому не может быть заверен. + %1$s завершил(а) голосовую трансляцию. + Вы завершили голосовую трансляцию. \ No newline at end of file From da9cfb6aafd823f64359d332f26a20508c9a6864 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sun, 18 Dec 2022 14:38:23 +0000 Subject: [PATCH 082/246] Translated using Weblate (Swedish) Currently translated at 100.0% (2568 of 2568 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- library/ui-strings/src/main/res/values-sv/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml index 1bf78ccf54..e8b903592c 100644 --- a/library/ui-strings/src/main/res/values-sv/strings.xml +++ b/library/ui-strings/src/main/res/values-sv/strings.xml @@ -2879,4 +2879,7 @@ Den här sessioner stöder inte kryptering och kan därför inte verifieras. Hämta det senaste bygget (obs: du kan ha problem med att logga in) Nightly-bygge + Direktsändning + Du avslutade en röstsändning. + %1$s avslutade en röstsändning. \ No newline at end of file From 905d6a32ed460728884cb918de20962b5e99b422 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sun, 18 Dec 2022 14:35:08 +0000 Subject: [PATCH 083/246] Translated using Weblate (Swedish) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40105120.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40105120.txt b/fastlane/metadata/android/sv-SE/changelogs/40105120.txt new file mode 100644 index 0000000000..d0f9c996af --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Trådar är nu aktivt som förval. +Full ändringslogg: https://github.com/vector-im/element-android/releases From ec4b7b0417b2ebc8d4bdfd01e702611fbb76b986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 19 Dec 2022 04:21:56 +0000 Subject: [PATCH 084/246] Translated using Weblate (Estonian) Currently translated at 100.0% (85 of 85 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40105120.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40105120.txt diff --git a/fastlane/metadata/android/et/changelogs/40105120.txt b/fastlane/metadata/android/et/changelogs/40105120.txt new file mode 100644 index 0000000000..9aadf5dae8 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on vaikimisi kasutusel. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From 5a60390338630a03e4ec4bc3f3fb2d3d3ea3ecb6 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Tue, 20 Dec 2022 07:09:04 +0000 Subject: [PATCH 085/246] Translated using Weblate (Czech) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 4df730f8cc..efb7dcd9d7 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2938,4 +2938,7 @@ Živé vysílání Ukončili jste hlasové vysílání. %1$s ukončil(a) hlasové vysílání. + Jste si jisti, že chcete ukončit živé vysílání\? Tím se vysílání ukončí a v místnosti bude k dispozici celý záznam. + Zastavit živé vysílání\? + Ano, zastavit \ No newline at end of file From ca3aae540cc46262cf5320be5841ae11f66f66c4 Mon Sep 17 00:00:00 2001 From: Vri Date: Tue, 20 Dec 2022 12:02:28 +0000 Subject: [PATCH 086/246] Translated using Weblate (German) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 588c6e93f0..66af20b36a 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2881,4 +2881,7 @@ Echtzeit-Übertragung Du hast eine Sprachübertragung beendet. %1$s beendete eine Sprachübertragung. + Möchtest du die Übertragung wirklich beenden\? Dies wird die Übertragung beenden und die vollständige Aufnahme im Raum bereitstellen. + Live-Übertragung beenden\? + Ja, beende \ No newline at end of file From e18b0819bfbbd4683a5f3e6391c5cc7f3a335da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 20 Dec 2022 06:01:06 +0000 Subject: [PATCH 087/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2563 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 8ac7097699..14d1ef5f8a 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2873,4 +2873,7 @@ Ringhäälingukõne on eetris Sa lõpetasid ringhäälingukõne. %1$s lõpetas ringhäälingukõne. + Kas sa oled kindel, et soovid otseeetri lõpetada\? Sellega ringhäälingukõne salvestamine lõppeb ja salvestis on kättesaadav kõigile jututoas. + Kas lõpetame otseeetri\? + Jah, lõpetame \ No newline at end of file From 2b6b723811805ee2e6f69205503d248be491d5b9 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Tue, 20 Dec 2022 06:10:12 +0000 Subject: [PATCH 088/246] Translated using Weblate (Persian) Currently translated at 100.0% (2571 of 2571 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 | 3 +++ 1 file changed, 3 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 eb5cf384dd..c1c7350da7 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2882,4 +2882,7 @@ پخش زنده به پخش صوتی پایان دادید. %1$s به پخش صوتی پایان داد. + مطمئنید که می‌خواهید پخش زنده‌تان را قطع کنید؟ این کار پخش را پایان داده و ضبط کامل در اتاق موجود خواهد شد. + قطع پخش زنده؟ + بله، متوقّف شود \ No newline at end of file From 24ec77104318c2f401b7047d014dbe2ec494cb1a Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 20 Dec 2022 08:35:56 +0000 Subject: [PATCH 089/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 ab21ea3b92..f94d61d34f 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2882,4 +2882,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Élő közvetítés A hang közvetítést befejezted. %1$s befejezte a hang közvetítést. + Biztos, hogy befejezed az élő közvetítést\? Ez befejezi a közvetítést és a felvétel az egész szoba számára elérhető lesz. + Megszakítod az élő közvetítést\? + Igen, befejez \ No newline at end of file From 2652ebec9306039ea069ee33493cc5c8d41eb454 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 20 Dec 2022 08:47:12 +0000 Subject: [PATCH 090/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- library/ui-strings/src/main/res/values-in/strings.xml | 5 ++++- 1 file changed, 4 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 c7d633846a..f706f22e31 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2648,7 +2648,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Aktivitas terakhir %1$s Perangkat Sesi - Sesi Saat Ini + 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. @@ -2828,4 +2828,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Siaran langsung Anda mengakhiri sebuah siaran suara. %1$s mengakhiri sebuah siaran suara. + Apakah Anda ingin menghentikan siaran langsung Anda\? Ini akan mengakhiri siaran dan rekaman lengkap akan tersedia dalam ruangan. + Hentikan siaran langsung\? + Ya, Hentikan \ No newline at end of file From 4ff47d9c8a73903247e6de3ace42eb21a992ff1f Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Tue, 20 Dec 2022 16:03:06 +0000 Subject: [PATCH 091/246] Translated using Weblate (Russian) Currently translated at 99.7% (2564 of 2571 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 | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 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 26fc66816f..d472c2f484 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -3,7 +3,7 @@ приглашение %s %1$s пригласил(а) %2$s %1$s пригласил(а) вас - %1$s вошёл(ла) в комнату + %1$s присоединился(лась) к комнате %1$s покинул(а) комнату %1$s отклонил(а) приглашение %1$s выгнан %2$s @@ -60,7 +60,7 @@ Приглашение %1$s. Причина: %2$s %1$s приглашен %2$s. Причина: %3$s %1$s пригласил вас. Причина: %2$s - %1$s вошёл(ла) в комнату. Причина: %2$s + %1$s присоединился(лась) к комнате. Причина: %2$s %1$s покинул(а) комнату. Причина: %2$s %1$s отклонил приглашение. Причина: %2$s %1$s выгнали %2$s. Причина: %3$s @@ -368,7 +368,7 @@ Системные настройки приложения. Сведения о приложении Уведомления для этой учётной записи - Уведомления для этой сессии + Уведомления для этого сеанса В персональных чатах В групповых чатах Когда меня приглашают в комнату @@ -433,7 +433,7 @@ Ошибка дешифровки Публичное название ID сеанса - Ключ сессии + Ключ сеанса Экспорт E2E ключей Экспорт ключей Экспорт ключей в локальный файл @@ -444,8 +444,8 @@ Импорт ключей Импортировать ключи из локального файла Импорт - Шифровать только для проверенных сессий - Не отправлять зашифрованные сообщения непроверенным сессиям с этой сессии. + Шифровать только для заверенных сеансов + Не отправлять зашифрованные сообщения незаверенным сеансам из этого сеанса. Не заверено Заверено Подтвердить @@ -494,7 +494,7 @@ Вызов Сообщения, содержащие мое имя пользователя Вы добавили новою сессию \'%s\', запрашивающую ключи шифрования. - Ваше непроверенная сессия \'%s\' запрашивает ключи шифрования. + Ваш незаверенный сеанс \'%s\' запрашивает ключи шифрования. Сообщения, содержащие моё отображаемое имя Начать проверку Звуковые уведомления @@ -661,9 +661,9 @@ Уведомления отключены для вашей учетной записи. \nПожалуйста, проверьте настройки аккаунта. Включить - Настройки сессии. + Настройки сеанса. Уведомления включены для этой сессии. - Уведомления не включены для этой сессии. + Уведомления не включены для этого сеанса. \nПожалуйста, проверьте настройки ${app_name}. Включить Проверка сервисов Play @@ -744,15 +744,15 @@ Удалить резервную копию ключей шифрования с сервера\? Вы больше не сможете использовать бумажный ключ для чтения истории зашифрованных сообщений. Удалить резервную копию Удаление резервной копии… - Чтобы использовать резервное копирование ключей в этой сессии, восстановите их с помощью мнемонической фразы или бумажного ключа. + Чтобы использовать резервное копирование ключей в этом сеансе, восстановите их с помощью мнемонической фразы или бумажного ключа. Резервная копия имеет недействительную подпись из подтвержденной сессии %s Резервная копия имеет действительную подпись из неподтвержденной сессии %s Резервная копия имеет действительную подпись из подтверждённой сессии %s. Резервная копия имеет действительную подпись с этой сессии. Резервная копия подписана сессией с идентификатором %s. Резервные копии ключей этой сессии не сохраняются. - Резервное копирование ключей не активировано в этой сессии. - Резервное копирование ключей успешно настроено для этой сессии. + Резервное копирование ключей не активировано в этом сеансе. + Резервное копирование ключей успешно настроено для этого сеанса. Удалить резервную копию Восстановить из резервной копии Пожалуйста, введите бумажный ключ @@ -866,14 +866,14 @@ неизвестный IP ** Отправить не удалось — пожалуйста, откройте комнату К сожалению, конференц-звонки с Jitsi не поддерживаются на старых устройствах (ниже Android OS - 6.0) - Новая сессия запрашивает ключи шифрования. -\nИмя сессии: %1$s -\nПоследний раз в сети: %2$s -\nЕсли вы не вошли с другой сессии, проигнорируйте этот запрос. - Непроверенная сессия запрашивает ключи шифрования. -\nИмя сессии: %1$s -\nПоследний раз в сети: %2$s -\nЕсли вы не открывали новую сессию - проигнорируйте этот запрос. + Новый сеанс запрашивает ключи шифрования. +\nНазвание сеанса: %1$s +\nПоследний раз в сети: %2$s +\nЕсли вы не входили в другой сеанс, проигнорируйте этот запрос. + Незаверенный сеанс запрашивает ключи шифрования. +\nНазвание сеанса: %1$s +\nПоследний раз в сети: %2$s +\nЕсли вы не входили в другой сеанс, проигнорируйте этот запрос. Поделиться Запрос поделится ключом Игнорировать @@ -932,7 +932,7 @@ ID приложения: Ключ Push: Отображаемое название приложения: - Отображаемое название сессии: + Отображаемое название сеанса: Url: Формат: Голос и видео @@ -1185,7 +1185,7 @@ Режим разработчика Режим разработчика активирует скрытые функции, а также может сделать приложение менее стабильным. Только для разработчиков! Настройки - Текущая сессия + Текущий сеанс Другие сеансы Включить шифрование Недоверенный вход @@ -1230,8 +1230,8 @@ Сообщение… Доступно обновление шифрования Проверьте себя и других для защиты ваших бесед - Подтвердите вход - Подтвердите свою личность и получите доступ к зашифрованным сообщениям, подтвердив этот вход в другой сессии. + Заверьте сеанс + Подтвердите свою личность и получите доступ к зашифрованным сообщениям, сверив этот сеанс с другим вашим сеансом. Лента сообщений Ключ сообщения Распечатайте его и храните в безопасном месте @@ -1429,7 +1429,7 @@ Сравните уникальные эмодзи, убедившись, что они появились в том же порядке. Сравните код с тем, который отображается на экране другого пользователя. Сообщения от этого пользователя зашифрованы сквозным шифрованием и не смогут быть прочитаны третьими лицами. - Ваша новая сессия подтверждена. Она имеет доступ к вашим зашифрованным сообщениям, и другие пользователи будут воспринимать её как заверенную. + Ваш новый сеанс заверен. Он имеет доступ к вашим зашифрованным сообщениям, и другие пользователи будут воспринимать его как заверенный. Перекрёстная подпись Перекрёстная подпись включена \nЛичные ключи хранятся на устройстве. @@ -1440,9 +1440,9 @@ \nКлючи не являются доверенными Перекрестная подпись выключена Администратор вашего сервера отключил сквозное шифрование по умолчанию в приватных комнатах и личных сообщениях. - Активные сессии - Показать все сессии - Управление сессиями + Активные сеансы + Показать все сеансы + Управление сеансами Выйти из этого сеанса Нет доступной криптографической информации @@ -1477,7 +1477,7 @@ Заверено Предупреждение Не удалось получить список сессий - Сессии + Сеансы Заверенная Незаверенная Эта сессия является доверенной для безопасного обмена сообщениями, так как %1$s (%2$s) проверил(а) его: @@ -1744,7 +1744,7 @@ Сбросить всё Забыли или потеряли все варианты восстановления\? Сбросить всё Вы вошли. - %s вошёл(ла). + %s присоединился(лась). Сообщения в этой переписке защищены сквозным шифрованием. Покинуть Настройки @@ -2417,7 +2417,7 @@ \n \nВы можете ознакомиться со всеми нашими условиями %s. Помогите улучшить ${app_name} - Сессия завершена! + Сеанс завершён! Комната покинута! Шифрование неправильно настроено, поэтому вы не можете отправлять сообщения. Нажмите, чтобы открыть настройки. Шифрование настроено неправильно, поэтому вы не можете отправлять сообщения. Пожалуйста, обратитесь к администратору, чтобы восстановить работу шифрования. @@ -2634,7 +2634,7 @@ Где хранятся ваши переписки Где будут храниться ваши переписки Должно быть 8 или более символов - Не удалось подтвердить эту сессию + Не удалось заверить этот сеанс Невозможно открыть эту ссылку: сообщества были заменены пространствами Имя пользователя / Почта / Телефон Следуйте инструкциям, отправленным на %s @@ -2663,7 +2663,7 @@ Все беседы Для лучшей защиты заверьте свои сеансы и выйдите из тех, которые более не признаёте или не используете. Другие сеансы - Сессии + Сеансы Создать беседу или комнату ЛС Настройки вида @@ -2724,13 +2724,13 @@ Информация о приложении, устройстве и активности. Заверьте текущий сеанс для усиления защиты переписки. Пока нет пространств. - Подтвердите свои сессии для более безопасного обмена сообщениями или выйдите из тех, которые более не признаёте или не используете. + Заверьте свои сеансы для усиления защиты переписки или выйдите из тех, которые более не признаёте или не используете. Заверьте или выйдите из незаверенных сеансов. Заверьте или выйдите из этого сеанса для лучшей безопасности и надёжности. Ничего нового. - Заверенных сессий не обнаружено. - Незаверенных сессий не обнаружено. - Неактивных сессий не обнаружено. + Заверенных сеансов не обнаружено. + Незаверенных сеансов не обнаружено. + Неактивных сеансов не обнаружено. Очистить фильтр Не готовы к защищенной переписке Готовы к защищенной переписке @@ -2758,16 +2758,16 @@ Запрещает клавиатуре обновлять персональные данные, такие как история набора текста и словарь, на основе того, что вы набрали при общении. Обратите внимание, что некоторые клавиатуры могут не соблюдать эту настройку. Понятно 🔒 В настройках безопасности вы включили шифрование только для заверенных сессий во всех комнатах. - Не отправлять зашифрованные сообщения незаверенным сессиям в этой комнате. - Неактивные сессии — это сессии, которыми вы не пользовались определённое время, но они продолжают получать ключи шифрования. + Не отправлять зашифрованные сообщения незаверенным сеансам в этой комнате. + Неактивные сеансы — это сеансы, которыми вы не пользовались определённое время, но они продолжают получать ключи шифрования. \n -\nУдаление неактивных сессий повышает безопасность и производительность, а также облегчает выявление подозрительных новых сессий. +\nУдаление неактивных сеансов повышает безопасность и производительность, а также облегчает выявление подозрительных новых сеансов. Переименование сеансов - Другие пользователи в личных сообщениях и комнатах, к которым вы присоединились, могут просматривать весь список ваших сессий. + Другие пользователи в личных сообщениях и комнатах, к которым вы присоединились, могут просматривать весь перечень ваших сеансов. \n -\nЭто даёт им уверенность в том, что они действительно общаются с вами, но это также означает, что они могут видеть название сессии, которое вы ввели здесь. +\nЭто даёт им уверенность в том, что они действительно общаются с вами, но это также означает, что они могут видеть название сеанса, которое вы ввели здесь. Наглядный текстовый редактор - ID сессии: + ID сеанса: Уведомления Получать push-уведомления в этой сессии. URL-адрес @@ -2777,25 +2777,25 @@ Веб-браузер Модель Операционная система - Новый менеджер сессий + Новый менеджер сеансов - Рассмотрите возможность выхода из старых сессий (%1$d день или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дня или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дней или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дней или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d день или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дня или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дней или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дней или дольше), которые вы более не используете. Результаты будут видны после завершения опроса Доступ к пространствам (внизу справа) быстрее и проще, чем когда-либо прежде. Доступ к пространствам - Рассмотрите возможность выхода из старых сессий (%1$d день или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дня или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дней или дольше), которые вы более не используете. - Рассмотрите возможность выхода из старых сессий (%1$d дней или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d день или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дня или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дней или дольше), которые вы более не используете. + Рассмотрите возможность выхода из старых сеансов (%1$d дней или дольше), которые вы более не используете. Голосовая трансляция Голосовые трансляции (в активной разработке) - Записывает название клиента, версию и URL-адрес для более лёгкого распознавания сессий в менеджере сессий. + Записывает название клиента, версию и URL-адрес для более лёгкого распознавания сеансов в менеджере сеансов. Записывать информацию о клиенте Галерея Наклейки @@ -2879,26 +2879,26 @@ Пространства — новый способ групировать комнаты и людей. Добавьте существующую комнату или создайте новую, используя кнопку слева снизу. Возможность записывать и отправлять голосовые трансляции в ленту комнаты. Получите лучший надзор и контроль над всеми вашими сессиями. - Подтверждённые сессии есть везде, где вы используете эту учётную запись, после введения вашего пароля или подтверждения вашей личности при помощи другой подтверждённой сессии. + Заверенные сеансы есть везде, где вы используете эту учётную запись после ввода своей мнемонической фразы или подтверждения своей личности с помощью другого заверенного сеанса. \n -\nЭто значит, что у вас есть все нужные ключи, чтобы разблокировать зашифрованные сообщения и даёте другим пользователям знать, что вы доверяете этой сессии. - Подтверждённые сессии вошли при помощи ваших учётных данных и были подтверждены, либо при помощи вашего безопасного пароля, либо при помощи подтверждения с другого устройства. +\nЭто означает, что у вас есть все ключи, необходимые для разблокировки ваших зашифрованных сообщений и подтверждения другим пользователям, что вы доверяете этому сеансу. + Заверенные сеансы — сеансы, которые вошли в систему с вашими учётными данными, а затем были заверены либо мнемонической фразой (бумажным ключом), либо путём перекрёстной сверки. \n -\nЭто значит, что на них находятся ключи шифрования для ваших предыдущих сообщений и дают другим пользователям знать, что эти сессии действительно принадлежат вам. - Неподтверждённые сессии — это сессии, которые вошли при помощи ваших учётных данных, но не были подтверждены. +\nЭто означает, что они хранят ключи шифрования от ваших предыдущих сообщений и подтверждают другим пользователям, с которыми вы общаетесь, что эти сеансы — действительно ваши. + Незаверенные сеансы — это сеансы, которые вошли в систему с вашими учётными данными, но не были перекрёстно заверены. \n -\nВы должны удостовериться, что узнаёте эти сессии, так как они могут быть несанкционированным входом в вашу учётную запись. +\nВы должны быть особенно уверены, что признаёте эти сеансы, поскольку они могут представлять собой несанкционированное использование вашей учётной записи. Вы можете использовать это устройство для входа с телефона или веб-устройства при помощи QR-кода. Для этого есть два способа: Войти по QR-коду Собственные названия сессий помогут вам легче распознать свои девайсы. - Выйти из %1$d сессии - Выйти из %1$d сессий - Выйти из %1$d сессий - Выйти из %1$d сессий + Выйти из %1$d сеанса + Выйти из %1$d сеансов + Выйти из %1$d сеансов + Выйти из %1$d сеансов Выйти - Выбрать сессии + Выбрать сеансы Фильтр Неактивен %1$d+ день (%2$s) From b60125a4dcd0742ae423ebaa9d7566d94dd0d668 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 20 Dec 2022 16:50:20 +0000 Subject: [PATCH 092/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 e49fcee9c7..277414d5e6 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2938,4 +2938,7 @@ Živé vysielanie Ukončili ste hlasové vysielanie. %1$s ukončil/a hlasové vysielanie. + Určite chcete zastaviť vysielanie naživo\? Tým sa vysielanie ukončí a v miestnosti bude k dispozícii celý záznam. + Zastaviť vysielanie naživo\? + Áno, zastaviť \ No newline at end of file From 815c6dbc6cbbcbf4c86e9d7d8aad32eca5605f95 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 20 Dec 2022 19:19:04 +0000 Subject: [PATCH 093/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2571 of 2571 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 | 3 +++ 1 file changed, 3 insertions(+) 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 6ac7809199..8e3286dd7f 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2994,4 +2994,7 @@ Трансляція наживо Ви завершили голосову трансляцію. %1$s завершує голосову трансляцію. + Ви впевнені, що хочете припинити голосову трансляцію\? На цьому трансляція завершиться, і повний запис буде доступний у кімнаті. + Припинити голосову трансляцію\? + Так, припинити \ No newline at end of file From 37c88636e142fc8b988a142c1742943b782eaa32 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 21 Dec 2022 01:47:13 +0000 Subject: [PATCH 094/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- library/ui-strings/src/main/res/values-zh-rTW/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 771d5adbeb..6cb8c675da 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 @@ -2826,4 +2826,7 @@ 即時廣播 您結束了語音廣播。 %1$s 結束了語音廣播。 + 您真的想要停止您的即時廣播嗎?這將會結束廣播,完整的錄音會在聊天室中提供。 + 停止即時廣播? + 是的,停止 \ No newline at end of file From a4761173fc4d31f230c36cc504120d61cf0b8c20 Mon Sep 17 00:00:00 2001 From: Vri Date: Tue, 20 Dec 2022 11:56:20 +0000 Subject: [PATCH 095/246] Translated using Weblate (German) Currently translated at 100.0% (86 of 86 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/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105130.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40105130.txt b/fastlane/metadata/android/de-DE/changelogs/40105130.txt new file mode 100644 index 0000000000..901b4c2a70 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Threads sind nun automatisch aktiviert. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From b2b51e0c30799444a9f354615dfcca8a9f8cb3e2 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Tue, 20 Dec 2022 09:33:28 +0000 Subject: [PATCH 096/246] Translated using Weblate (Russian) Currently translated at 98.8% (85 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ru/ --- fastlane/metadata/android/ru-RU/changelogs/40105120.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40105130.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40105120.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40105130.txt diff --git a/fastlane/metadata/android/ru-RU/changelogs/40105120.txt b/fastlane/metadata/android/ru-RU/changelogs/40105120.txt new file mode 100644 index 0000000000..047e0254ae --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Обсуждения теперь включены по умолчанию. +Перечень всех изменений: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/ru-RU/changelogs/40105130.txt b/fastlane/metadata/android/ru-RU/changelogs/40105130.txt new file mode 100644 index 0000000000..047e0254ae --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Обсуждения теперь включены по умолчанию. +Перечень всех изменений: https://github.com/vector-im/element-android/releases From 684aaa982dfe6e847796385f3865ac65a9500536 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 20 Dec 2022 16:49:41 +0000 Subject: [PATCH 097/246] Translated using Weblate (Slovak) Currently translated at 100.0% (86 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40105130.txt diff --git a/fastlane/metadata/android/sk/changelogs/40105130.txt b/fastlane/metadata/android/sk/changelogs/40105130.txt new file mode 100644 index 0000000000..d5b5ad330d --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna sú teraz predvolene zapnuté. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From aad61cd2e4c4683688d73d8dc6916f26ad85bffc Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 20 Dec 2022 19:20:56 +0000 Subject: [PATCH 098/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (86 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40105130.txt diff --git a/fastlane/metadata/android/uk/changelogs/40105130.txt b/fastlane/metadata/android/uk/changelogs/40105130.txt new file mode 100644 index 0000000000..edbd209d17 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Гілки відтепер типово ввімкнено. +Перелік усіх змін: https://github.com/vector-im/element-android/releases From 175a6bac153d645b3296bff79185f06d5cc70ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 20 Dec 2022 05:58:49 +0000 Subject: [PATCH 099/246] Translated using Weblate (Estonian) Currently translated at 100.0% (86 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40105130.txt diff --git a/fastlane/metadata/android/et/changelogs/40105130.txt b/fastlane/metadata/android/et/changelogs/40105130.txt new file mode 100644 index 0000000000..c8f1e98c3d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on nüüd vaikimisi kasutusel. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From 64bd148463305b9ab8f812fe0dbdb09c026a07b0 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Tue, 20 Dec 2022 06:08:18 +0000 Subject: [PATCH 100/246] Translated using Weblate (Persian) Currently translated at 100.0% (86 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105130.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105130.txt b/fastlane/metadata/android/fa/changelogs/40105130.txt new file mode 100644 index 0000000000..0c3cc5aa31 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105130.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رشته‌ها اکنون به صورت پیش‌گزیده به کار افتاده‌اند. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 1e1c849099a1fe23b961282772236e0035c56373 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 21 Dec 2022 01:45:18 +0000 Subject: [PATCH 101/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (86 of 86 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/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105130.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105130.txt b/fastlane/metadata/android/zh-TW/changelogs/40105130.txt new file mode 100644 index 0000000000..9c66f3c2ad --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105130.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串現在預設啟用。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From e5e70f51d6ed64c5bf6dc697b8aa8e7b1210eb17 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Tue, 20 Dec 2022 07:09:42 +0000 Subject: [PATCH 102/246] Translated using Weblate (Czech) Currently translated at 100.0% (86 of 86 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/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105130.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105130.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105130.txt new file mode 100644 index 0000000000..69c2b3304c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From 384ddeb9fdc5884cc5800e8954b2e97e0183ca67 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 20 Dec 2022 08:45:30 +0000 Subject: [PATCH 103/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (86 of 86 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40105130.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40105130.txt diff --git a/fastlane/metadata/android/id/changelogs/40105130.txt b/fastlane/metadata/android/id/changelogs/40105130.txt new file mode 100644 index 0000000000..173a1bfb1b --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Utasan sekarang diaktifkan secara bawaan. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From f640c07343fa16398d8fe10b1985a77f4d2920a8 Mon Sep 17 00:00:00 2001 From: Vri Date: Wed, 21 Dec 2022 08:02:03 +0000 Subject: [PATCH 104/246] Translated using Weblate (German) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 66af20b36a..3f4730e376 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -471,7 +471,7 @@ Raum %s ist nicht sichtbar. Integrationen hinzufügen Benachrichtigungston - Anfrage konnte nicht gesendet werden. + Übertragung der Anfrage fehlgeschlagen. user_id fehlt in der Anfrage. Helles Design Dunkles Design From 3f1b7bd22a94b9f697b8ba23df701c486e27562c Mon Sep 17 00:00:00 2001 From: Glandos Date: Wed, 21 Dec 2022 09:12:39 +0000 Subject: [PATCH 105/246] Translated using Weblate (French) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- library/ui-strings/src/main/res/values-fr/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 e659e2f416..a11b879efd 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2882,4 +2882,7 @@ Version Nightly Vous avez terminé une diffusion audio. %1$s a terminé une diffusion audio. + Êtes-vous sûr de vouloir arrêter votre diffusion en direct \? Cela terminera la diffusion et l’enregistrement complet sera disponible dans le salon. + Arrêter la diffusion en direct \? + Oui, arrêter \ No newline at end of file From c5cb5571d96e6e16e8173bd463e0dc942894526f Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 22 Dec 2022 08:46:21 +0000 Subject: [PATCH 106/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 f94d61d34f..b2a82d21e8 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2702,7 +2702,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze 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. + Ellenőrizd az aktuális munkamenetet a biztonságos üzenetküldéshez. 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 From 9373adfc8678317339bdbaa9f8f4febf4ee3c8f3 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 21 Dec 2022 09:44:14 +0000 Subject: [PATCH 107/246] Translated using Weblate (Italian) Currently translated at 100.0% (2571 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- library/ui-strings/src/main/res/values-it/strings.xml | 3 +++ 1 file changed, 3 insertions(+) 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 211ea642e4..0b29e5f18f 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2873,4 +2873,7 @@ Nightly build Hai terminato una trasmissione vocale. %1$s ha terminato una trasmissione vocale. + Vuoi davvero fermare la tua trasmissione in diretta\? Verrà terminata la trasmissione e la registrazione completa sarà disponibile nella stanza. + Fermare la trasmissione in diretta\? + Sì, ferma \ No newline at end of file From c3fa1b3865e6789cedf322fcde6b58f54bfdf92a Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Wed, 21 Dec 2022 11:37:45 +0000 Subject: [PATCH 108/246] Translated using Weblate (Russian) Currently translated at 99.7% (2564 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 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 d472c2f484..0fec10bebd 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -3,7 +3,7 @@ приглашение %s %1$s пригласил(а) %2$s %1$s пригласил(а) вас - %1$s присоединился(лась) к комнате + %1$s вошёл(шла) в комнату %1$s покинул(а) комнату %1$s отклонил(а) приглашение %1$s выгнан %2$s @@ -1744,7 +1744,7 @@ Сбросить всё Забыли или потеряли все варианты восстановления\? Сбросить всё Вы вошли. - %s присоединился(лась). + %s вошёл(шла). Сообщения в этой переписке защищены сквозным шифрованием. Покинуть Настройки From dfdd0a28a963de942eaa9e56c3af83a07f600cc1 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 21 Dec 2022 16:33:41 +0000 Subject: [PATCH 109/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2554 of 2571 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- library/ui-strings/src/main/res/values-sq/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index 119c948c5a..3d08cf8115 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2573,7 +2573,7 @@ Filtroji Pajisje Sesion - Sesioni i Tanishëm + Sesioni i tanishëm Shihni mundësinë e daljes nga sesione të vjetër (%1$d ditë ose më tepër) të cilët s’i përdorni më. Shihni mundësinë e daljes nga sesione të vjetër (%1$d ditë ose më tepër) të cilët s’i përdorni më. @@ -2867,4 +2867,7 @@ Montim i përnatshëm Përfunduat një transmetim zanor. %1$s përfundoi një transmetim zanor. + Jeni i sigurt se doni të ndalet transmetimi juaj i drejtpërdrejtë\? Kjo do të përfundojë transmetimin dhe regjistrimi i plotë do të jetë i passhëm te dhoma. + Të ndalet transmetimi i drejtpërdrejtë\? + Po, Ndale \ No newline at end of file From 84083c0b9779ca007d8d297b5b792dd7c2a45879 Mon Sep 17 00:00:00 2001 From: Vri Date: Wed, 21 Dec 2022 07:58:06 +0000 Subject: [PATCH 110/246] Translated using Weblate (German) Currently translated at 100.0% (87 of 87 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/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105140.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40105140.txt b/fastlane/metadata/android/de-DE/changelogs/40105140.txt new file mode 100644 index 0000000000..c55d8d998f --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Threads sind nun standardmäßig aktiviert. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From bc95beecc4e68e01d38757e71f1434f2ce6ef138 Mon Sep 17 00:00:00 2001 From: Tuomas Hietala Date: Thu, 22 Dec 2022 23:37:29 +0000 Subject: [PATCH 111/246] Translated using Weblate (Finnish) Currently translated at 14.9% (13 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fi/ --- fastlane/metadata/android/fi-FI/full_description.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fastlane/metadata/android/fi-FI/full_description.txt b/fastlane/metadata/android/fi-FI/full_description.txt index ac02bc3b42..a1defe8131 100644 --- a/fastlane/metadata/android/fi-FI/full_description.txt +++ b/fastlane/metadata/android/fi-FI/full_description.txt @@ -1,4 +1,4 @@ -Element on turvallinen pikaviesti- ja tiimityösovellus joka sopii mainiosti ryhmäkeskusteluihin etätöissä. Sovellus käyttää päästä päähän -salausta ja tarjoaa videoneuvottelun, tiedostojen jakamisen ja äänipuhelut. +Element on turvallinen pikaviesti- ja tiimityösovellus, joka sopii mainiosti ryhmäkeskusteluihin etätöissä. Sovellus käyttää läpisalausta ja tarjoaa videoneuvottelun, tiedostojen jakamisen ja äänipuhelut. Elementin ominaisuuksia: - Edistyneet viestintätyökalut @@ -35,5 +35,8 @@ Real end-to-end encryption (only those in the conversation can decrypt messages) Kattavaa viestintää ja integraatioita Viestit, ääni- ja videopuhelut, tiedostojen jakaminen, näytön jakaminen ja koko joukko integraatioita, botteja ja sovelmia. Luo huoneita ja yhteisöjä, pidä yhteyttä ja hoida asiasi. -Jatka siitä mihin jäit -Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://app.element.io +Jatka siitä, mihin jäit +Täysin synkronoitu viestihistoria kaikkien laitteidesi välillä ja verkkoselaimessa: https://app.element.io + +Avointa lähdekoodia +Element Android on avoimen lähdekoodin projekti GitHubissa. Ilmoita virheistä ja osallistu kehittämiseen osoitteessa https://github.com/vector-im/element-android From 9db2c38b7baf1a783b6b83db66ea21d99ef795be Mon Sep 17 00:00:00 2001 From: Glandos Date: Wed, 21 Dec 2022 09:09:20 +0000 Subject: [PATCH 112/246] Translated using Weblate (French) Currently translated at 100.0% (87 of 87 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/40105130.txt | 2 ++ fastlane/metadata/android/fr-FR/changelogs/40105140.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105130.txt create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105140.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105130.txt b/fastlane/metadata/android/fr-FR/changelogs/40105130.txt new file mode 100644 index 0000000000..4101bb0c86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Fils de discussion activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105140.txt b/fastlane/metadata/android/fr-FR/changelogs/40105140.txt new file mode 100644 index 0000000000..4101bb0c86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Fils de discussion activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases From f5c0b9536e6af0a9ae0afccb94980fab9fe5e638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?E=C3=B6tv=C3=B6s=20K=C3=A1roly?= Date: Thu, 22 Dec 2022 19:12:46 +0000 Subject: [PATCH 113/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/hu/ --- fastlane/metadata/android/hu-HU/changelogs/40105000.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105020.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105040.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105060.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105070.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105080.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105100.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105110.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105120.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105130.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105140.txt | 2 ++ 11 files changed, 22 insertions(+) create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105000.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105020.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105040.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105060.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105070.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105080.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105100.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105110.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105120.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105130.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105140.txt diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105000.txt b/fastlane/metadata/android/hu-HU/changelogs/40105000.txt new file mode 100644 index 0000000000..7298a41794 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105000.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: A késleltetett DM alapból engedélyezve van. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105020.txt b/fastlane/metadata/android/hu-HU/changelogs/40105020.txt new file mode 100644 index 0000000000..1686d93813 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105020.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Új app layout alapból bekapcsolva! +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105040.txt b/fastlane/metadata/android/hu-HU/changelogs/40105040.txt new file mode 100644 index 0000000000..9821c573de --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105040.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Új funkciók a laboratórium beállítások alatt: Gazdag szöveg kompózer, új eszköz kezelése, hangközvetítés. Még mindig aktív fejlesztés alatt! +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105060.txt b/fastlane/metadata/android/hu-HU/changelogs/40105060.txt new file mode 100644 index 0000000000..f62af5db6b --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105060.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Új felhasználói felület a mellékletek kiválasztására. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105070.txt b/fastlane/metadata/android/hu-HU/changelogs/40105070.txt new file mode 100644 index 0000000000..f62af5db6b --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105070.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Új felhasználói felület a mellékletek kiválasztására. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105080.txt b/fastlane/metadata/android/hu-HU/changelogs/40105080.txt new file mode 100644 index 0000000000..de2fe57fe1 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105080.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: bugfixek és javítások +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105100.txt b/fastlane/metadata/android/hu-HU/changelogs/40105100.txt new file mode 100644 index 0000000000..560103b913 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105100.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: A teljes képernyős mód új megvalósítása a Rich Text Editor számára és hibajavítások. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105110.txt b/fastlane/metadata/android/hu-HU/changelogs/40105110.txt new file mode 100644 index 0000000000..560103b913 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105110.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: A teljes képernyős mód új megvalósítása a Rich Text Editor számára és hibajavítások. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105120.txt b/fastlane/metadata/android/hu-HU/changelogs/40105120.txt new file mode 100644 index 0000000000..a4e7c9acb9 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Threadek már alapból engedélyezve vannak. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105130.txt b/fastlane/metadata/android/hu-HU/changelogs/40105130.txt new file mode 100644 index 0000000000..a4e7c9acb9 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Threadek már alapból engedélyezve vannak. +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105140.txt b/fastlane/metadata/android/hu-HU/changelogs/40105140.txt new file mode 100644 index 0000000000..a4e7c9acb9 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Threadek már alapból engedélyezve vannak. +Teljes változási napló: https://github.com/vector-im/element-android/releases From 3208a0095a1e776730615e6bfd18da282e4b9a75 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Wed, 21 Dec 2022 15:45:35 +0000 Subject: [PATCH 114/246] Translated using Weblate (Slovak) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40105140.txt diff --git a/fastlane/metadata/android/sk/changelogs/40105140.txt b/fastlane/metadata/android/sk/changelogs/40105140.txt new file mode 100644 index 0000000000..d5b5ad330d --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna sú teraz predvolene zapnuté. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From 9a932a168667e3dc306108106a84723e29092209 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Wed, 21 Dec 2022 21:21:22 +0000 Subject: [PATCH 115/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40105140.txt diff --git a/fastlane/metadata/android/uk/changelogs/40105140.txt b/fastlane/metadata/android/uk/changelogs/40105140.txt new file mode 100644 index 0000000000..edbd209d17 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Гілки відтепер типово ввімкнено. +Перелік усіх змін: https://github.com/vector-im/element-android/releases From 7d259bdce87a4fdbfd7a47fe7c89d84ccebbc5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 21 Dec 2022 06:56:40 +0000 Subject: [PATCH 116/246] Translated using Weblate (Estonian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40105140.txt diff --git a/fastlane/metadata/android/et/changelogs/40105140.txt b/fastlane/metadata/android/et/changelogs/40105140.txt new file mode 100644 index 0000000000..c8f1e98c3d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on nüüd vaikimisi kasutusel. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From 8d88e30588dd7549ba8b81b85655bb723813e339 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 21 Dec 2022 09:49:05 +0000 Subject: [PATCH 117/246] Translated using Weblate (Italian) Currently translated at 100.0% (87 of 87 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/40105130.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/40105140.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40105130.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/40105140.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40105130.txt b/fastlane/metadata/android/it-IT/changelogs/40105130.txt new file mode 100644 index 0000000000..ab24842e82 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: i messaggi in conversazioni sono attivi in modo predefinito. +Cronologia completa: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/it-IT/changelogs/40105140.txt b/fastlane/metadata/android/it-IT/changelogs/40105140.txt new file mode 100644 index 0000000000..ab24842e82 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: i messaggi in conversazioni sono attivi in modo predefinito. +Cronologia completa: https://github.com/vector-im/element-android/releases From 9600e9ef2e0853df7724465b4e7de97a688c7697 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 21 Dec 2022 06:15:12 +0000 Subject: [PATCH 118/246] Translated using Weblate (Persian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105140.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105140.txt b/fastlane/metadata/android/fa/changelogs/40105140.txt new file mode 100644 index 0000000000..0c3cc5aa31 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105140.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رشته‌ها اکنون به صورت پیش‌گزیده به کار افتاده‌اند. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 66060f8387a6bcfb15ff36b1f587f3b521cb40ec Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 22 Dec 2022 01:50:06 +0000 Subject: [PATCH 119/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (87 of 87 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/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105140.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105140.txt b/fastlane/metadata/android/zh-TW/changelogs/40105140.txt new file mode 100644 index 0000000000..9c66f3c2ad --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105140.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串現在預設啟用。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From c007708b9ccbe96a99055b8128d2d9fb8d877453 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 21 Dec 2022 07:04:02 +0000 Subject: [PATCH 120/246] Translated using Weblate (Czech) Currently translated at 100.0% (87 of 87 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/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105140.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105140.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105140.txt new file mode 100644 index 0000000000..69c2b3304c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From f2ee10b85fd394ac9e3653f6a8586de4337b57d7 Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 21 Dec 2022 03:44:19 +0000 Subject: [PATCH 121/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40105140.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40105140.txt diff --git a/fastlane/metadata/android/id/changelogs/40105140.txt b/fastlane/metadata/android/id/changelogs/40105140.txt new file mode 100644 index 0000000000..173a1bfb1b --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Utasan sekarang diaktifkan secara bawaan. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From 9f054342d0d17454c03c3397877346f94d7999ab Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 21 Dec 2022 16:32:18 +0000 Subject: [PATCH 122/246] Translated using Weblate (Albanian) Currently translated at 100.0% (87 of 87 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40105130.txt | 2 ++ fastlane/metadata/android/sq/changelogs/40105140.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/sq/changelogs/40105130.txt create mode 100644 fastlane/metadata/android/sq/changelogs/40105140.txt diff --git a/fastlane/metadata/android/sq/changelogs/40105130.txt b/fastlane/metadata/android/sq/changelogs/40105130.txt new file mode 100644 index 0000000000..51350f5c00 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Rrjedhat tanimë janë të aktivizuara, si parazgjedhje. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sq/changelogs/40105140.txt b/fastlane/metadata/android/sq/changelogs/40105140.txt new file mode 100644 index 0000000000..51350f5c00 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Rrjedhat tanimë janë të aktivizuara, si parazgjedhje. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases From 1ff7e16b197a321a21349bf2f399927a9a456896 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Sat, 24 Dec 2022 11:13:20 +0000 Subject: [PATCH 123/246] Translated using Weblate (Czech) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 efb7dcd9d7..0a7998deaa 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2941,4 +2941,9 @@ Jste si jisti, že chcete ukončit živé vysílání\? Tím se vysílání ukončí a v místnosti bude k dispozici celý záznam. Zastavit živé vysílání\? Ano, zastavit + Upravit odkaz + Vytvořit odkaz + Odkaz + Text + Nastavit odkaz \ No newline at end of file From db89b98242db8a97eb5391fb0cc81ef5d8e9d56a Mon Sep 17 00:00:00 2001 From: Vri Date: Sat, 24 Dec 2022 07:07:14 +0000 Subject: [PATCH 124/246] Translated using Weblate (German) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 3f4730e376..5f1a47eba2 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2884,4 +2884,9 @@ Möchtest du die Übertragung wirklich beenden\? Dies wird die Übertragung beenden und die vollständige Aufnahme im Raum bereitstellen. Live-Übertragung beenden\? Ja, beende + Link setzen + Link bearbeiten + Link erstellen + Link + Text \ No newline at end of file From 45824eb2fd0a7613ec0d4739b5ceb232fd8f9402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 24 Dec 2022 08:01:51 +0000 Subject: [PATCH 125/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2568 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 14d1ef5f8a..20592ff831 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2876,4 +2876,9 @@ Kas sa oled kindel, et soovid otseeetri lõpetada\? Sellega ringhäälingukõne salvestamine lõppeb ja salvestis on kättesaadav kõigile jututoas. Kas lõpetame otseeetri\? Jah, lõpetame + Seadista linki + Tekst + Link + Loo link + Muuda linki \ No newline at end of file From bde9718de4278783a33f7e32b5402ed4c18c3e21 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Sat, 24 Dec 2022 00:57:57 +0000 Subject: [PATCH 126/246] Translated using Weblate (Persian) Currently translated at 100.0% (2576 of 2576 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 c1c7350da7..e7d0640050 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2885,4 +2885,9 @@ مطمئنید که می‌خواهید پخش زنده‌تان را قطع کنید؟ این کار پخش را پایان داده و ضبط کامل در اتاق موجود خواهد شد. قطع پخش زنده؟ بله، متوقّف شود + ویرایش پیوند + ایجاد پیوند + پیوند + متن + تنظیم پیوند \ No newline at end of file From 11d1c2086dc3da29a9f537f93c7a7a6e7d8efb4b Mon Sep 17 00:00:00 2001 From: Glandos Date: Sat, 24 Dec 2022 08:49:39 +0000 Subject: [PATCH 127/246] Translated using Weblate (French) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- library/ui-strings/src/main/res/values-fr/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 a11b879efd..abe34dc579 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2885,4 +2885,9 @@ Êtes-vous sûr de vouloir arrêter votre diffusion en direct \? Cela terminera la diffusion et l’enregistrement complet sera disponible dans le salon. Arrêter la diffusion en direct \? Oui, arrêter + Éditer le lien + Crée un lien + Lien + Texte + Définir un lien \ No newline at end of file From 29a0e4700c57df9f5af926981ca9290c8a40a539 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 24 Dec 2022 09:33:41 +0000 Subject: [PATCH 128/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 b2a82d21e8..b527a8fbab 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2885,4 +2885,9 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Biztos, hogy befejezed az élő közvetítést\? Ez befejezi a közvetítést és a felvétel az egész szoba számára elérhető lesz. Megszakítod az élő közvetítést\? Igen, befejez + Hivatkozás szerkesztése + Hivatkozás készítése + Hivatkozás + Szöveg + Hivatkozás beállítása \ No newline at end of file From 52f88c4bb1e80de6bf992195d2bec863a3533dc3 Mon Sep 17 00:00:00 2001 From: Linerly Date: Sun, 25 Dec 2022 15:43:11 +0000 Subject: [PATCH 129/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2576 of 2576 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 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) 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 f706f22e31..835346979c 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -344,7 +344,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Nama Perangkat Terakhir terlihat %1$s @ %2$s - Otentikasi + Autentikasi Masuk sebagai Homeserver Server identitas @@ -610,7 +610,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Meminta untuk konfirmasi sebelum memulai panggilan Cegah panggilan tidak disengaja - Tidak sah, tidak ada kredensial otentikasi yang absah + Tidak sah, tidak ada kredensial autentikasi yang absah Kesalahan SSL. Kesalahan SSL: identitas peer belum diverifikasi. Tidak dapat mencapai homeserver pada URL ini, silakan periksa @@ -2108,9 +2108,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Impor kunci dari file Buka widget Tangkap layar - Gagal mengotentikasi + Gagal mengautentikasi ${app_name} meminta Anda untuk memasukkan kredensial untuk melakukan tindakan ini. - Otentikasi Ulang Dibutuhkan + Autentikasi Ulang Dibutuhkan Geser untuk mengakhirkan panggilan Orang tak dikenal Pindah ke %1$s @@ -2467,8 +2467,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Sinkronisasi latar belakang Layanan Google Pilih cara untuk menerima notifikasi - Tidak dapat mengaktifkan otentikasi biometrik. - Otentikasi biometrik dinonaktifkan karena sebuah otentikasi biometrik telah ditambahkan baru-baru ini. Anda dapat mengaktifkan ulang di Pengaturan. + Tidak dapat mengaktifkan autentikasi biometrik. + Autentikasi biometrik dinonaktifkan karena sebuah autentikasi biometrik telah ditambahkan baru-baru ini. Anda dapat mengaktifkan ulang di Pengaturan. Atur ulang metode notifikasi Tag profil: Gagal mendaftarkan token endpoint ke homeserver: @@ -2831,4 +2831,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Apakah Anda ingin menghentikan siaran langsung Anda\? Ini akan mengakhiri siaran dan rekaman lengkap akan tersedia dalam ruangan. Hentikan siaran langsung\? Ya, Hentikan + Sunting tautan + Buat sebuah tautan + Tautan + Teks + Atur tautan \ No newline at end of file From c558baa036535eb1844ea2966342eca666447203 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 24 Dec 2022 18:44:49 +0000 Subject: [PATCH 130/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2576 of 2576 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 | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 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 e083da85f5..1b6a342d4c 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 @@ -480,7 +480,7 @@ Som de notificação Mnsgns contendo meu nome de exibição Mnsgns contendo meu nome de usuária(o) - Previsualização de URL emlinha + Previsualização de URL inline Mostrar timestamps em formato de 12 horas Vibrar ao mencionar um/uma usuário(a) Analítica @@ -2356,7 +2356,7 @@ Falha para carregar mapa Mapa Nota: app vai ser recomeçado - Habilitar Mensagens de Thread + Habilitar mensagens com threads Conectar a servidor Procurando se juntar a um servidor existente\? Pular esta pergunta @@ -2700,7 +2700,7 @@ Última atividade %1$s Dispositivo Sessão - Sessão Atual + 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. @@ -2879,7 +2879,15 @@ Você tem sessões não-verificadas Obtenha a build mais recente (note: você pode ter problema para fazer signin) Build nightly - Transmissão ao vivo - Você terminou uma transmissão de voz. - %1$s terminou uma transmissão de voz. + Broadcast ao vivo + Você terminou um broadcast de voz. + %1$s terminou um broadcast de voz. + Editar link + Criar um link + Link + Texto + Definir link + Tem certeza que você quer parar seu broadcast ao vivo\? Isto vai terminar o broadcast e a gravação completa vai estar disponível na sala. + Parar de fazer broadcasting ao vivo\? + Sim, Parar \ No newline at end of file From cb60c177a06c15524d327ebe9bbcb8022356fdb3 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Sat, 24 Dec 2022 12:32:08 +0000 Subject: [PATCH 131/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 277414d5e6..e3c78c9128 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2941,4 +2941,9 @@ Určite chcete zastaviť vysielanie naživo\? Tým sa vysielanie ukončí a v miestnosti bude k dispozícii celý záznam. Zastaviť vysielanie naživo\? Áno, zastaviť + Upraviť odkaz + Vytvoriť odkaz + Odkaz + Text + Nastaviť odkaz \ No newline at end of file From 83481ac329745a1e87839ab743d55924af67313b Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sat, 24 Dec 2022 20:18:36 +0000 Subject: [PATCH 132/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2576 of 2576 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 | 5 +++++ 1 file changed, 5 insertions(+) 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 8e3286dd7f..6af8bc4ed6 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2997,4 +2997,9 @@ Ви впевнені, що хочете припинити голосову трансляцію\? На цьому трансляція завершиться, і повний запис буде доступний у кімнаті. Припинити голосову трансляцію\? Так, припинити + Змінити посилання + Створити посилання + Посилання + Текст + Налаштувати посилання \ No newline at end of file From 773da7dda9bdacb5e7b77ac724d0cf56a9ba634d Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 24 Dec 2022 18:43:58 +0000 Subject: [PATCH 133/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (87 of 87 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/40105120.txt | 2 ++ fastlane/metadata/android/pt-BR/changelogs/40105130.txt | 2 ++ fastlane/metadata/android/pt-BR/changelogs/40105140.txt | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40105120.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40105130.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40105140.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40105120.txt b/fastlane/metadata/android/pt-BR/changelogs/40105120.txt new file mode 100644 index 0000000000..0e5e1a9401 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40105120.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Threads são agora habilitadas por padrão. +Changelog completo: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/pt-BR/changelogs/40105130.txt b/fastlane/metadata/android/pt-BR/changelogs/40105130.txt new file mode 100644 index 0000000000..0e5e1a9401 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40105130.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Threads são agora habilitadas por padrão. +Changelog completo: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/pt-BR/changelogs/40105140.txt b/fastlane/metadata/android/pt-BR/changelogs/40105140.txt new file mode 100644 index 0000000000..0e5e1a9401 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40105140.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Threads são agora habilitadas por padrão. +Changelog completo: https://github.com/vector-im/element-android/releases From c3ad7faa2c951d232471a52d68c870a2bb347400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Dec 2022 23:02:43 +0000 Subject: [PATCH 134/246] Bump dependency-check-gradle from 7.4.1 to 7.4.3 Bumps dependency-check-gradle from 7.4.1 to 7.4.3. --- 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 0f94fc418c..7e5d659c8b 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ buildscript { classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5' classpath "com.likethesalad.android:stem-plugin:2.2.3" - classpath 'org.owasp:dependency-check-gradle:7.4.1' + classpath 'org.owasp:dependency-check-gradle:7.4.3' classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.20" classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0" classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3' From 5ee3eefe964a4dc77f2cae24dafe3a1088fa2332 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 2 Jan 2023 16:55:25 +0100 Subject: [PATCH 135/246] Pull branch sooner to ensure release version is correctly guessed --- tools/release/releaseScript.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/release/releaseScript.sh b/tools/release/releaseScript.sh index 8273914c88..553c02101c 100755 --- a/tools/release/releaseScript.sh +++ b/tools/release/releaseScript.sh @@ -87,6 +87,14 @@ fi printf "OK\n" +printf "\n================================================================================\n" +printf "Ensuring main and develop branches are up to date...\n" + +git checkout main +git pull +git checkout develop +git pull + printf "\n================================================================================\n" # Guessing version to propose a default version versionMajorCandidate=`grep "ext.versionMajor" ./vector-app/build.gradle | cut -d " " -f3` @@ -103,14 +111,6 @@ versionMinor=`echo ${version} | cut -d "." -f2` versionPatch=`echo ${version} | cut -d "." -f3` nextPatchVersion=$((versionPatch + 2)) -printf "\n================================================================================\n" -printf "Ensuring main and develop branches are up to date...\n" - -git checkout main -git pull -git checkout develop -git pull - printf "\n================================================================================\n" printf "Starting the release ${version}\n" git flow release start ${version} From 56986c3a77b77b19ea9be782543719e0bdffccf5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 2 Jan 2023 21:15:08 +0100 Subject: [PATCH 136/246] Add a way to get the access token from the advances settings. --- library/ui-strings/src/main/res/values/strings.xml | 3 +++ .../settings/VectorSettingsAdvancedSettingsFragment.kt | 9 +++++++++ .../main/res/xml/vector_settings_advanced_settings.xml | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 73cb60bb68..1aad226dcf 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3501,4 +3501,7 @@ sent a video. sent a sticker. created a poll. + + Access Token + Your access token gives full access to your account. Do not share it with anyone. diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedSettingsFragment.kt index b6fa997f41..514f2529e9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedSettingsFragment.kt @@ -25,6 +25,7 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.preference.VectorPreference import im.vector.app.core.preference.VectorPreferenceCategory import im.vector.app.core.preference.VectorSwitchPreference +import im.vector.app.core.utils.copyToClipboard import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.NightlyProxy import im.vector.app.features.rageshake.RageShake @@ -64,6 +65,14 @@ class VectorSettingsAdvancedSettingsFragment : override fun bindPref() { setupRageShakeSection() setupNightlySection() + setupDevToolsSection() + } + + private fun setupDevToolsSection() { + findPreference("SETTINGS_ACCESS_TOKEN")?.setOnPreferenceClickListener { + copyToClipboard(requireActivity(), session.sessionParams.credentials.accessToken) + true + } } private fun setupRageShakeSection() { diff --git a/vector/src/main/res/xml/vector_settings_advanced_settings.xml b/vector/src/main/res/xml/vector_settings_advanced_settings.xml index 9260b33162..6399d54cbb 100644 --- a/vector/src/main/res/xml/vector_settings_advanced_settings.xml +++ b/vector/src/main/res/xml/vector_settings_advanced_settings.xml @@ -93,6 +93,12 @@ android:title="@string/settings_key_requests" app:fragment="im.vector.app.features.settings.devtools.KeyRequestsFragment" /> + + Date: Tue, 3 Jan 2023 11:55:32 +0100 Subject: [PATCH 137/246] Avoid launching coroutine for nothing. --- .../sdk/internal/session/StreamEventsManager.kt | 10 ++++------ .../session/sync/handler/room/RoomSyncHandler.kt | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt index cfc26045a0..ce34b0430e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt @@ -42,14 +42,12 @@ internal class StreamEventsManager @Inject constructor() { listeners.remove(listener) } - fun dispatchLiveEventReceived(event: Event, roomId: String, initialSync: Boolean) { + fun dispatchLiveEventReceived(event: Event, roomId: String) { Timber.v("## dispatchLiveEventReceived ${event.eventId}") coroutineScope.launch { - if (!initialSync) { - listeners.forEach { - tryOrNull { - it.onLiveEvent(roomId, event) - } + listeners.forEach { + tryOrNull { + it.onLiveEvent(roomId, event) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 4001ae2ccf..d67b903bb9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -423,7 +423,9 @@ internal class RoomSyncHandler @Inject constructor( val isInitialSync = insertType == EventInsertType.INITIAL_SYNC eventIds.add(event.eventId) - liveEventService.get().dispatchLiveEventReceived(event, roomId, isInitialSync) + if (!isInitialSync) { + liveEventService.get().dispatchLiveEventReceived(event, roomId) + } if (event.isEncrypted() && !isInitialSync) { try { From 0e504e90145f021a7a1867184cc1a373dc5a5c2d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 11:55:41 +0100 Subject: [PATCH 138/246] Format --- .../session/sync/handler/room/RoomSyncHandler.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index d67b903bb9..ccc3820bb6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -376,8 +376,15 @@ internal class RoomSyncHandler @Inject constructor( roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) } roomTypingUsersHandler.handle(realm, roomId, null) roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE) - roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, - roomSync.unreadNotifications, roomSync.unreadThreadNotifications, aggregator = aggregator) + roomSummaryUpdater.update( + realm, + roomId, + membership, + roomSync.summary, + roomSync.unreadNotifications, + roomSync.unreadThreadNotifications, + aggregator = aggregator, + ) return roomEntity } From 6f384c799f46fe63c55b71a3590a8b0349861bbd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 15:02:45 +0100 Subject: [PATCH 139/246] Batch insertion of `shouldShareHistory` --- .../internal/crypto/DefaultCryptoService.kt | 2 ++ .../internal/crypto/store/IMXCryptoStore.kt | 3 +++ .../crypto/store/db/CryptoStoreAggregator.kt | 21 +++++++++++++++ .../crypto/store/db/RealmCryptoStore.kt | 26 ++++++++++++++++--- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 7862da1c17..128f06eacb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -384,6 +384,7 @@ internal class DefaultCryptoService @Inject constructor( } } } + cryptoStore.onSyncWillProcess() } private fun internalStart() { @@ -432,6 +433,7 @@ internal class DefaultCryptoService @Inject constructor( * @param syncResponse the syncResponse */ fun onSyncCompleted(syncResponse: SyncResponse) { + cryptoStore.onSyncCompleted() cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { if (syncResponse.deviceLists != null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 21e3342365..a285dbec78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -48,6 +48,9 @@ import org.matrix.olm.OlmOutboundGroupSession */ internal interface IMXCryptoStore { + fun onSyncWillProcess() + fun onSyncCompleted() + /** * @return the device id */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt new file mode 100644 index 0000000000..529cad6869 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.store.db + +data class CryptoStoreAggregator( + val setShouldShareHistoryData: MutableMap = mutableMapOf() +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 1b52b79746..a98a7ee0ec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -716,9 +716,7 @@ internal class RealmCryptoStore @Inject constructor( override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) { Timber.tag(loggerTag.value) .v("setShouldShareHistory for room $roomId is $shouldShareHistory") - doRealmTransaction(realmConfiguration) { - CryptoRoomEntity.getOrCreate(it, roomId).shouldShareHistory = shouldShareHistory - } + cryptoStoreAggregator?.setShouldShareHistoryData?.put(roomId, shouldShareHistory) } override fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) { @@ -1815,4 +1813,26 @@ internal class RealmCryptoStore @Inject constructor( // Can we do something for WithHeldSessionEntity? } } + + private var cryptoStoreAggregator: CryptoStoreAggregator? = null + override fun onSyncWillProcess() { + if (cryptoStoreAggregator != null) { + Timber.e("cryptoStoreAggregator is not null...") + } + cryptoStoreAggregator = CryptoStoreAggregator() + } + + override fun onSyncCompleted() { + val aggregator = cryptoStoreAggregator ?: return Unit.also { + Timber.e("cryptoStoreAggregator is null...") + } + + doRealmTransaction("onSyncCompleted", realmConfiguration) { realm -> + // setShouldShareHistory + aggregator.setShouldShareHistoryData.map { + CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value + } + } + cryptoStoreAggregator = null + } } From c1a8bf828b9b5569a2e6498c7eec99a1d2c8597b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 15:15:15 +0100 Subject: [PATCH 140/246] Batch insertion of `shouldEncryptForInvitedMembers` --- .../sdk/internal/crypto/store/db/CryptoStoreAggregator.kt | 3 ++- .../sdk/internal/crypto/store/db/RealmCryptoStore.kt | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt index 529cad6869..165062f17c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt @@ -17,5 +17,6 @@ package org.matrix.android.sdk.internal.crypto.store.db data class CryptoStoreAggregator( - val setShouldShareHistoryData: MutableMap = mutableMapOf() + val setShouldShareHistoryData: MutableMap = mutableMapOf(), + val setShouldEncryptForInvitedMembersData: MutableMap = mutableMapOf(), ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index a98a7ee0ec..3f9e22140e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -708,9 +708,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) { - doRealmTransaction(realmConfiguration) { - CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers - } + cryptoStoreAggregator?.setShouldEncryptForInvitedMembersData?.put(roomId, shouldEncryptForInvitedMembers) } override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) { @@ -1832,6 +1830,10 @@ internal class RealmCryptoStore @Inject constructor( aggregator.setShouldShareHistoryData.map { CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value } + // setShouldEncryptForInvitedMembers + aggregator.setShouldEncryptForInvitedMembersData.map { + CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value + } } cryptoStoreAggregator = null } From a386a4762c13ac13922382d7ee119de10b67dd67 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 15:18:32 +0100 Subject: [PATCH 141/246] Crypto store: Log realm transactions and the duration --- .../sdk/internal/crypto/store/db/Helper.kt | 12 ++- .../crypto/store/db/RealmCryptoStore.kt | 84 +++++++++---------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt index 2d66ce1488..6412df205f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt @@ -20,10 +20,12 @@ import android.util.Base64 import io.realm.Realm import io.realm.RealmConfiguration import io.realm.RealmObject +import timber.log.Timber import java.io.ByteArrayOutputStream import java.io.ObjectOutputStream import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream +import kotlin.system.measureTimeMillis /** * Get realm, invoke the action, close realm, and return the result of the action. @@ -55,10 +57,12 @@ internal fun doRealmQueryAndCopyList(realmConfiguration: Realm /** * Get realm instance, invoke the action in a transaction and close realm. */ -internal fun doRealmTransaction(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { - Realm.getInstance(realmConfiguration).use { realm -> - realm.executeTransaction { action.invoke(it) } - } +internal fun doRealmTransaction(tag: String, realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { + measureTimeMillis { + Realm.getInstance(realmConfiguration).use { realm -> + realm.executeTransaction { action.invoke(it) } + } + }.also { Timber.w("doRealmTransaction for $tag took $it millis") } } internal fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 3f9e22140e..c62dd7f5c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -147,7 +147,7 @@ internal class RealmCryptoStore @Inject constructor( init { // Ensure CryptoMetadataEntity is inserted in DB - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("init", realmConfiguration) { realm -> var currentMetadata = realm.where().findFirst() var deleteAll = false @@ -189,7 +189,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun deleteStore() { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("deleteStore", realmConfiguration) { it.deleteAll() } } @@ -218,7 +218,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun storeDeviceId(deviceId: String) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("storeDeviceId", realmConfiguration) { it.where().findFirst()?.deviceId = deviceId } } @@ -230,7 +230,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun saveOlmAccount() { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("saveOlmAccount", realmConfiguration) { it.where().findFirst()?.putOlmAccount(olmAccount) } } @@ -248,7 +248,7 @@ internal class RealmCryptoStore @Inject constructor( @Synchronized override fun getOrCreateOlmAccount(): OlmAccount { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("getOrCreateOlmAccount", realmConfiguration) { val metaData = it.where().findFirst() val existing = metaData!!.getOlmAccount() if (existing == null) { @@ -288,7 +288,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun storeUserDevices(userId: String, devices: Map?) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeUserDevices", realmConfiguration) { realm -> if (devices == null) { Timber.d("Remove user $userId") // Remove the user @@ -331,7 +331,7 @@ internal class RealmCryptoStore @Inject constructor( selfSigningKey: CryptoCrossSigningKey?, userSigningKey: CryptoCrossSigningKey? ) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeUserCrossSigningKeys", realmConfiguration) { realm -> UserEntity.getOrCreate(realm, userId) .let { userEntity -> if (masterKey == null || selfSigningKey == null) { @@ -480,7 +480,7 @@ internal class RealmCryptoStore @Inject constructor( override fun storePrivateKeysInfo(msk: String?, usk: String?, ssk: String?) { Timber.v("## CRYPTO | *** storePrivateKeysInfo ${msk != null}, ${usk != null}, ${ssk != null}") - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storePrivateKeysInfo", realmConfiguration) { realm -> realm.where().findFirst()?.apply { xSignMasterPrivateKey = msk xSignUserPrivateKey = usk @@ -490,7 +490,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("saveBackupRecoveryKey", realmConfiguration) { realm -> realm.where().findFirst()?.apply { keyBackupRecoveryKey = recoveryKey keyBackupRecoveryKeyVersion = version @@ -516,7 +516,7 @@ internal class RealmCryptoStore @Inject constructor( override fun storeMSKPrivateKey(msk: String?) { Timber.v("## CRYPTO | *** storeMSKPrivateKey ${msk != null} ") - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeMSKPrivateKey", realmConfiguration) { realm -> realm.where().findFirst()?.apply { xSignMasterPrivateKey = msk } @@ -525,7 +525,7 @@ internal class RealmCryptoStore @Inject constructor( override fun storeSSKPrivateKey(ssk: String?) { Timber.v("## CRYPTO | *** storeSSKPrivateKey ${ssk != null} ") - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeSSKPrivateKey", realmConfiguration) { realm -> realm.where().findFirst()?.apply { xSignSelfSignedPrivateKey = ssk } @@ -534,7 +534,7 @@ internal class RealmCryptoStore @Inject constructor( override fun storeUSKPrivateKey(usk: String?) { Timber.v("## CRYPTO | *** storeUSKPrivateKey ${usk != null} ") - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeUSKPrivateKey", realmConfiguration) { realm -> realm.where().findFirst()?.apply { xSignUserPrivateKey = usk } @@ -667,7 +667,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun storeRoomAlgorithm(roomId: String, algorithm: String?) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("storeRoomAlgorithm", realmConfiguration) { CryptoRoomEntity.getOrCreate(it, roomId).let { entity -> entity.algorithm = algorithm // store anyway the new algorithm, but mark the room @@ -729,7 +729,7 @@ internal class RealmCryptoStore @Inject constructor( if (sessionIdentifier != null) { val key = OlmSessionEntity.createPrimaryKey(sessionIdentifier, deviceKey) - doRealmTransaction(realmConfiguration) { + doRealmTransaction("storeSession", realmConfiguration) { val realmOlmSession = OlmSessionEntity().apply { primaryKey = key sessionId = sessionIdentifier @@ -786,7 +786,7 @@ internal class RealmCryptoStore @Inject constructor( return } - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("storeInboundGroupSessions", realmConfiguration) { realm -> sessions.forEach { wrapper -> val sessionIdentifier = try { @@ -910,7 +910,7 @@ internal class RealmCryptoStore @Inject constructor( override fun removeInboundGroupSession(sessionId: String, senderKey: String) { val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey) - doRealmTransaction(realmConfiguration) { + doRealmTransaction("removeInboundGroupSession", realmConfiguration) { it.where() .equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key) .findAll() @@ -929,7 +929,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setKeyBackupVersion(keyBackupVersion: String?) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("setKeyBackupVersion", realmConfiguration) { it.where().findFirst()?.backupVersion = keyBackupVersion } } @@ -941,7 +941,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setKeysBackupData(keysBackupData: KeysBackupDataEntity?) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("setKeysBackupData", realmConfiguration) { if (keysBackupData == null) { // Clear the table it.where() @@ -955,7 +955,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun resetBackupMarkers() { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("resetBackupMarkers", realmConfiguration) { it.where() .findAll() .map { inboundGroupSession -> @@ -969,7 +969,7 @@ internal class RealmCryptoStore @Inject constructor( return } - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("markBackupDoneForInboundGroupSessions", realmConfiguration) { realm -> olmInboundGroupSessionWrappers.forEach { olmInboundGroupSessionWrapper -> try { val sessionIdentifier = @@ -1028,13 +1028,13 @@ internal class RealmCryptoStore @Inject constructor( } override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("setGlobalBlacklistUnverifiedDevices", realmConfiguration) { it.where().findFirst()?.globalBlacklistUnverifiedDevices = block } } override fun enableKeyGossiping(enable: Boolean) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("enableKeyGossiping", realmConfiguration) { it.where().findFirst()?.globalEnableKeyGossiping = enable } } @@ -1058,13 +1058,13 @@ internal class RealmCryptoStore @Inject constructor( } override fun enableShareKeyOnInvite(enable: Boolean) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("enableShareKeyOnInvite", realmConfiguration) { it.where().findFirst()?.enableKeyForwardingOnInvite = enable } } override fun setDeviceKeysUploaded(uploaded: Boolean) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("setDeviceKeysUploaded", realmConfiguration) { it.where().findFirst()?.deviceKeysSentToServer = uploaded } } @@ -1111,7 +1111,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun blockUnverifiedDevicesInRoom(roomId: String, block: Boolean) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("blockUnverifiedDevicesInRoom", realmConfiguration) { realm -> CryptoRoomEntity.getById(realm, roomId) ?.blacklistUnverifiedDevices = block } @@ -1131,7 +1131,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun saveDeviceTrackingStatuses(deviceTrackingStatuses: Map) { - doRealmTransaction(realmConfiguration) { + doRealmTransaction("saveDeviceTrackingStatuses", realmConfiguration) { deviceTrackingStatuses .map { entry -> UserEntity.getOrCreate(it, entry.key) @@ -1264,7 +1264,7 @@ internal class RealmCryptoStore @Inject constructor( ): OutgoingKeyRequest { // Insert the request and return the one passed in parameter lateinit var request: OutgoingKeyRequest - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("getOrAddOutgoingRoomKeyRequest", realmConfiguration) { realm -> val existing = realm.where() .equalTo(OutgoingKeyRequestEntityFields.MEGOLM_SESSION_ID, requestBody.sessionId) @@ -1302,7 +1302,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun updateOutgoingRoomKeyRequestState(requestId: String, newState: OutgoingRoomKeyRequestState) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("updateOutgoingRoomKeyRequestState", realmConfiguration) { realm -> realm.where() .equalTo(OutgoingKeyRequestEntityFields.REQUEST_ID, requestId) .findFirst()?.apply { @@ -1316,7 +1316,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun updateOutgoingRoomKeyRequiredIndex(requestId: String, newIndex: Int) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("updateOutgoingRoomKeyRequiredIndex", realmConfiguration) { realm -> realm.where() .equalTo(OutgoingKeyRequestEntityFields.REQUEST_ID, requestId) .findFirst()?.apply { @@ -1333,7 +1333,7 @@ internal class RealmCryptoStore @Inject constructor( fromDevice: String?, event: Event ) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("updateOutgoingRoomKeyReply", realmConfiguration) { realm -> realm.where() .equalTo(OutgoingKeyRequestEntityFields.ROOM_ID, roomId) .equalTo(OutgoingKeyRequestEntityFields.MEGOLM_SESSION_ID, sessionId) @@ -1349,7 +1349,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun deleteOutgoingRoomKeyRequest(requestId: String) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("deleteOutgoingRoomKeyRequest", realmConfiguration) { realm -> realm.where() .equalTo(OutgoingKeyRequestEntityFields.REQUEST_ID, requestId) .findFirst()?.deleteOnCascade() @@ -1357,7 +1357,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun deleteOutgoingRoomKeyRequestInState(state: OutgoingRoomKeyRequestState) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("deleteOutgoingRoomKeyRequestInState", realmConfiguration) { realm -> realm.where() .equalTo(OutgoingKeyRequestEntityFields.REQUEST_STATE_STR, state.name) .findAll() @@ -1493,7 +1493,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setMyCrossSigningInfo(info: MXCrossSigningInfo?) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("setMyCrossSigningInfo", realmConfiguration) { realm -> realm.where().findFirst()?.userId?.let { userId -> addOrUpdateCrossSigningInfo(realm, userId, info) } @@ -1501,7 +1501,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setUserKeysAsTrusted(userId: String, trusted: Boolean) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("setUserKeysAsTrusted", realmConfiguration) { realm -> val xInfoEntity = realm.where(CrossSigningInfoEntity::class.java) .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) .findFirst() @@ -1521,7 +1521,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean?) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("setDeviceTrust", realmConfiguration) { realm -> realm.where(DeviceInfoEntity::class.java) .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId)) .findFirst()?.let { deviceInfoEntity -> @@ -1541,7 +1541,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun clearOtherUserTrust() { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("clearOtherUserTrust", realmConfiguration) { realm -> val xInfoEntities = realm.where(CrossSigningInfoEntity::class.java) .findAll() xInfoEntities?.forEach { info -> @@ -1556,7 +1556,7 @@ internal class RealmCryptoStore @Inject constructor( } override fun updateUsersTrust(check: (String) -> Boolean) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("updateUsersTrust", realmConfiguration) { realm -> val xInfoEntities = realm.where(CrossSigningInfoEntity::class.java) .findAll() xInfoEntities?.forEach { xInfoEntity -> @@ -1664,13 +1664,13 @@ internal class RealmCryptoStore @Inject constructor( } override fun setCrossSigningInfo(userId: String, info: MXCrossSigningInfo?) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("setCrossSigningInfo", realmConfiguration) { realm -> addOrUpdateCrossSigningInfo(realm, userId, info) } } override fun markMyMasterKeyAsLocallyTrusted(trusted: Boolean) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("markMyMasterKeyAsLocallyTrusted", realmConfiguration) { realm -> realm.where().findFirst()?.userId?.let { myUserId -> CrossSigningInfoEntity.get(realm, myUserId)?.getMasterKey()?.let { xInfoEntity -> val level = xInfoEntity.trustLevelEntity @@ -1709,7 +1709,7 @@ internal class RealmCryptoStore @Inject constructor( val roomId = withHeldContent.roomId ?: return val sessionId = withHeldContent.sessionId ?: return if (withHeldContent.algorithm != MXCRYPTO_ALGORITHM_MEGOLM) return - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("addWithHeldMegolmSession", realmConfiguration) { realm -> WithHeldSessionEntity.getOrCreate(realm, roomId, sessionId)?.let { it.code = withHeldContent.code it.senderKey = withHeldContent.senderKey @@ -1741,7 +1741,7 @@ internal class RealmCryptoStore @Inject constructor( deviceIdentityKey: String, chainIndex: Int ) { - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("markedSessionAsShared", realmConfiguration) { realm -> SharedSessionEntity.create( realm = realm, roomId = roomId, @@ -1790,7 +1790,7 @@ internal class RealmCryptoStore @Inject constructor( */ override fun tidyUpDataBase() { val prevWeekTs = clock.epochMillis() - 7 * 24 * 60 * 60 * 1_000 - doRealmTransaction(realmConfiguration) { realm -> + doRealmTransaction("tidyUpDataBase", realmConfiguration) { realm -> // Clean the old ones? realm.where() From f26178fc211efb9f0fa7fe56267401fd2a2a494a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 15:21:03 +0100 Subject: [PATCH 142/246] Avoid useless transaction --- .../sdk/internal/crypto/store/db/CryptoStoreAggregator.kt | 7 ++++++- .../sdk/internal/crypto/store/db/RealmCryptoStore.kt | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt index 165062f17c..687ec95ec3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/CryptoStoreAggregator.kt @@ -19,4 +19,9 @@ package org.matrix.android.sdk.internal.crypto.store.db data class CryptoStoreAggregator( val setShouldShareHistoryData: MutableMap = mutableMapOf(), val setShouldEncryptForInvitedMembersData: MutableMap = mutableMapOf(), -) +) { + fun isEmpty(): Boolean { + return setShouldShareHistoryData.isEmpty() && + setShouldEncryptForInvitedMembersData.isEmpty() + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index c62dd7f5c2..949043f2db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -1824,7 +1824,11 @@ internal class RealmCryptoStore @Inject constructor( val aggregator = cryptoStoreAggregator ?: return Unit.also { Timber.e("cryptoStoreAggregator is null...") } + cryptoStoreAggregator = null + if (aggregator.isEmpty()) { + return + } doRealmTransaction("onSyncCompleted", realmConfiguration) { realm -> // setShouldShareHistory aggregator.setShouldShareHistoryData.map { @@ -1835,6 +1839,5 @@ internal class RealmCryptoStore @Inject constructor( CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value } } - cryptoStoreAggregator = null } } From 4c4ef0d73eca19e846c553456d9f9e500276328c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 15:57:39 +0100 Subject: [PATCH 143/246] Batch insertion of user data after downloading keys. --- .../sdk/internal/crypto/DeviceListManager.kt | 14 +- .../internal/crypto/store/IMXCryptoStore.kt | 2 + .../internal/crypto/store/UserDataToStore.kt | 25 ++ .../crypto/store/db/RealmCryptoStore.kt | 236 ++++++++++-------- 4 files changed, 165 insertions(+), 112 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index 7e9e156003..f6e08ce9f7 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.UserDataToStore import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.sync.SyncTokenStore @@ -371,6 +372,8 @@ internal class DeviceListManager @Inject constructor( Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users") } + val userDataToStore = UserDataToStore() + for (userId in filteredUsers) { // al devices = val models = response.deviceKeys?.get(userId)?.mapValues { entry -> CryptoInfoMapper.map(entry.value) } @@ -404,7 +407,7 @@ internal class DeviceListManager @Inject constructor( } // Update the store // Note that devices which aren't in the response will be removed from the stores - cryptoStore.storeUserDevices(userId, workingCopy) + userDataToStore.userDevices[userId] = workingCopy } val masterKey = response.masterKeys?.get(userId)?.toCryptoModel().also { @@ -416,14 +419,11 @@ internal class DeviceListManager @Inject constructor( val userSigningKey = response.userSigningKeys?.get(userId)?.toCryptoModel()?.also { Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}") } - cryptoStore.storeUserCrossSigningKeys( - userId, - masterKey, - selfSigningKey, - userSigningKey - ) + userDataToStore.userCrossSigningKeys[userId] = Triple(masterKey, selfSigningKey, userSigningKey) } + cryptoStore.storeUserDataToStore(userDataToStore) + // Update devices trust for these users // dispatchDeviceChange(downloadUsers) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index a285dbec78..92a92ab36a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -583,4 +583,6 @@ internal interface IMXCryptoStore { fun areDeviceKeysUploaded(): Boolean fun tidyUpDataBase() fun getOutgoingRoomKeyRequests(inStates: Set): List + + fun storeUserDataToStore(userDataToStore: UserDataToStore) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt new file mode 100644 index 0000000000..05afc75e5a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.store + +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo + +internal data class UserDataToStore( + val userDevices: MutableMap> = mutableMapOf(), + val userCrossSigningKeys: MutableMap> = mutableMapOf(), +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 949043f2db..83ff960d53 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrappe import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.UserDataToStore import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity @@ -289,37 +290,41 @@ internal class RealmCryptoStore @Inject constructor( override fun storeUserDevices(userId: String, devices: Map?) { doRealmTransaction("storeUserDevices", realmConfiguration) { realm -> - if (devices == null) { - Timber.d("Remove user $userId") - // Remove the user - UserEntity.delete(realm, userId) - } else { - val userEntity = UserEntity.getOrCreate(realm, userId) - // First delete the removed devices - val deviceIds = devices.keys - userEntity.devices.toTypedArray().iterator().let { - while (it.hasNext()) { - val deviceInfoEntity = it.next() - if (deviceInfoEntity.deviceId !in deviceIds) { - Timber.d("Remove device ${deviceInfoEntity.deviceId} of user $userId") - deviceInfoEntity.deleteOnCascade() - } + storeUserDevices(realm, userId, devices) + } + } + + private fun storeUserDevices(realm: Realm, userId: String, devices: Map?) { + if (devices == null) { + Timber.d("Remove user $userId") + // Remove the user + UserEntity.delete(realm, userId) + } else { + val userEntity = UserEntity.getOrCreate(realm, userId) + // First delete the removed devices + val deviceIds = devices.keys + userEntity.devices.toTypedArray().iterator().let { + while (it.hasNext()) { + val deviceInfoEntity = it.next() + if (deviceInfoEntity.deviceId !in deviceIds) { + Timber.d("Remove device ${deviceInfoEntity.deviceId} of user $userId") + deviceInfoEntity.deleteOnCascade() } } - // Then update existing devices or add new one - devices.values.forEach { cryptoDeviceInfo -> - val existingDeviceInfoEntity = userEntity.devices.firstOrNull { it.deviceId == cryptoDeviceInfo.deviceId } - if (existingDeviceInfoEntity == null) { - // Add the device - Timber.d("Add device ${cryptoDeviceInfo.deviceId} of user $userId") - val newEntity = CryptoMapper.mapToEntity(cryptoDeviceInfo) - newEntity.firstTimeSeenLocalTs = clock.epochMillis() - userEntity.devices.add(newEntity) - } else { - // Update the device - Timber.d("Update device ${cryptoDeviceInfo.deviceId} of user $userId") - CryptoMapper.updateDeviceInfoEntity(existingDeviceInfoEntity, cryptoDeviceInfo) - } + } + // Then update existing devices or add new one + devices.values.forEach { cryptoDeviceInfo -> + val existingDeviceInfoEntity = userEntity.devices.firstOrNull { it.deviceId == cryptoDeviceInfo.deviceId } + if (existingDeviceInfoEntity == null) { + // Add the device + Timber.d("Add device ${cryptoDeviceInfo.deviceId} of user $userId") + val newEntity = CryptoMapper.mapToEntity(cryptoDeviceInfo) + newEntity.firstTimeSeenLocalTs = clock.epochMillis() + userEntity.devices.add(newEntity) + } else { + // Update the device + Timber.d("Update device ${cryptoDeviceInfo.deviceId} of user $userId") + CryptoMapper.updateDeviceInfoEntity(existingDeviceInfoEntity, cryptoDeviceInfo) } } } @@ -332,85 +337,95 @@ internal class RealmCryptoStore @Inject constructor( userSigningKey: CryptoCrossSigningKey? ) { doRealmTransaction("storeUserCrossSigningKeys", realmConfiguration) { realm -> - UserEntity.getOrCreate(realm, userId) - .let { userEntity -> - if (masterKey == null || selfSigningKey == null) { - // The user has disabled cross signing? - userEntity.crossSigningInfoEntity?.deleteOnCascade() - userEntity.crossSigningInfoEntity = null - } else { - var shouldResetMyDevicesLocalTrust = false - CrossSigningInfoEntity.getOrCreate(realm, userId).let { signingInfo -> - // What should we do if we detect a change of the keys? - val existingMaster = signingInfo.getMasterKey() - if (existingMaster != null && existingMaster.publicKeyBase64 == masterKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingMaster, masterKey) - } else { - Timber.d("## CrossSigning MSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(masterKey) - signingInfo.setMasterKey(keyEntity) - if (userId == this.userId) { - shouldResetMyDevicesLocalTrust = true - // my msk has changed! clear my private key - // Could we have some race here? e.g I am the one that did change the keys - // could i get this update to early and clear the private keys? - // -> initializeCrossSigning is guarding for that by storing all at once - realm.where().findFirst()?.apply { - xSignMasterPrivateKey = null - } + storeUserCrossSigningKeys(realm, userId, masterKey, selfSigningKey, userSigningKey) + } + } + + private fun storeUserCrossSigningKeys( + realm: Realm, + userId: String, + masterKey: CryptoCrossSigningKey?, + selfSigningKey: CryptoCrossSigningKey?, + userSigningKey: CryptoCrossSigningKey? + ) { + UserEntity.getOrCreate(realm, userId) + .let { userEntity -> + if (masterKey == null || selfSigningKey == null) { + // The user has disabled cross signing? + userEntity.crossSigningInfoEntity?.deleteOnCascade() + userEntity.crossSigningInfoEntity = null + } else { + var shouldResetMyDevicesLocalTrust = false + CrossSigningInfoEntity.getOrCreate(realm, userId).let { signingInfo -> + // What should we do if we detect a change of the keys? + val existingMaster = signingInfo.getMasterKey() + if (existingMaster != null && existingMaster.publicKeyBase64 == masterKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingMaster, masterKey) + } else { + Timber.d("## CrossSigning MSK change for $userId") + val keyEntity = crossSigningKeysMapper.map(masterKey) + signingInfo.setMasterKey(keyEntity) + if (userId == this.userId) { + shouldResetMyDevicesLocalTrust = true + // my msk has changed! clear my private key + // Could we have some race here? e.g I am the one that did change the keys + // could i get this update to early and clear the private keys? + // -> initializeCrossSigning is guarding for that by storing all at once + realm.where().findFirst()?.apply { + xSignMasterPrivateKey = null } } - - val existingSelfSigned = signingInfo.getSelfSignedKey() - if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == selfSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingSelfSigned, selfSigningKey) - } else { - Timber.d("## CrossSigning SSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(selfSigningKey) - signingInfo.setSelfSignedKey(keyEntity) - if (userId == this.userId) { - shouldResetMyDevicesLocalTrust = true - // my ssk has changed! clear my private key - realm.where().findFirst()?.apply { - xSignSelfSignedPrivateKey = null - } - } - } - - // Only for me - if (userSigningKey != null) { - val existingUSK = signingInfo.getUserSigningKey() - if (existingUSK != null && existingUSK.publicKeyBase64 == userSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingUSK, userSigningKey) - } else { - Timber.d("## CrossSigning USK change for $userId") - val keyEntity = crossSigningKeysMapper.map(userSigningKey) - signingInfo.setUserSignedKey(keyEntity) - if (userId == this.userId) { - shouldResetMyDevicesLocalTrust = true - // my usk has changed! clear my private key - realm.where().findFirst()?.apply { - xSignUserPrivateKey = null - } - } - } - } - - // When my cross signing keys are reset, we consider clearing all existing device trust - if (shouldResetMyDevicesLocalTrust) { - realm.where() - .equalTo(UserEntityFields.USER_ID, this.userId) - .findFirst() - ?.devices?.forEach { - it?.trustLevelEntity?.crossSignedVerified = false - it?.trustLevelEntity?.locallyVerified = it.deviceId == deviceId - } - } - userEntity.crossSigningInfoEntity = signingInfo } + + val existingSelfSigned = signingInfo.getSelfSignedKey() + if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == selfSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingSelfSigned, selfSigningKey) + } else { + Timber.d("## CrossSigning SSK change for $userId") + val keyEntity = crossSigningKeysMapper.map(selfSigningKey) + signingInfo.setSelfSignedKey(keyEntity) + if (userId == this.userId) { + shouldResetMyDevicesLocalTrust = true + // my ssk has changed! clear my private key + realm.where().findFirst()?.apply { + xSignSelfSignedPrivateKey = null + } + } + } + + // Only for me + if (userSigningKey != null) { + val existingUSK = signingInfo.getUserSigningKey() + if (existingUSK != null && existingUSK.publicKeyBase64 == userSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingUSK, userSigningKey) + } else { + Timber.d("## CrossSigning USK change for $userId") + val keyEntity = crossSigningKeysMapper.map(userSigningKey) + signingInfo.setUserSignedKey(keyEntity) + if (userId == this.userId) { + shouldResetMyDevicesLocalTrust = true + // my usk has changed! clear my private key + realm.where().findFirst()?.apply { + xSignUserPrivateKey = null + } + } + } + } + + // When my cross signing keys are reset, we consider clearing all existing device trust + if (shouldResetMyDevicesLocalTrust) { + realm.where() + .equalTo(UserEntityFields.USER_ID, this.userId) + .findFirst() + ?.devices?.forEach { + it?.trustLevelEntity?.crossSignedVerified = false + it?.trustLevelEntity?.locallyVerified = it.deviceId == deviceId + } + } + userEntity.crossSigningInfoEntity = signingInfo } } - } + } } override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { @@ -1831,13 +1846,24 @@ internal class RealmCryptoStore @Inject constructor( } doRealmTransaction("onSyncCompleted", realmConfiguration) { realm -> // setShouldShareHistory - aggregator.setShouldShareHistoryData.map { + aggregator.setShouldShareHistoryData.forEach { CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value } // setShouldEncryptForInvitedMembers - aggregator.setShouldEncryptForInvitedMembersData.map { + aggregator.setShouldEncryptForInvitedMembersData.forEach { CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value } } } + + override fun storeUserDataToStore(userDataToStore: UserDataToStore) { + doRealmTransaction("storeUserDataToStore", realmConfiguration) { realm -> + userDataToStore.userDevices.forEach { + storeUserDevices(realm, it.key, it.value) + } + userDataToStore.userCrossSigningKeys.forEach { + storeUserCrossSigningKeys(realm, it.key, it.value.first, it.value.second, it.value.third) + } + } + } } From 02e7157206404ea07c2544ac6e590c30ae201f98 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 16:16:17 +0100 Subject: [PATCH 144/246] Introduce CryptoCrossSigningKeys container --- .../crosssigning/CryptoCrossSigningKeys.kt | 26 ++++++++++++++ .../sdk/internal/crypto/DeviceListManager.kt | 7 +++- .../internal/crypto/store/IMXCryptoStore.kt | 5 ++- .../internal/crypto/store/UserDataToStore.kt | 4 +-- .../crypto/store/db/RealmCryptoStore.kt | 36 +++++++++---------- 5 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt new file mode 100644 index 0000000000..e0a422b54b --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2023 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.crypto.crosssigning + +/** + * Container for the three cross signing keys: master, self signing and user signing. + */ +data class CryptoCrossSigningKeys( + val masterKey: CryptoCrossSigningKey?, + val selfSigningKey: CryptoCrossSigningKey?, + val userSigningKey: CryptoCrossSigningKey?, +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index f6e08ce9f7..8ced0864d0 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.extensions.measureMetric import org.matrix.android.sdk.api.metrics.DownloadDeviceKeysMetricsPlugin +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap @@ -419,7 +420,11 @@ internal class DeviceListManager @Inject constructor( val userSigningKey = response.userSigningKeys?.get(userId)?.toCryptoModel()?.also { Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}") } - userDataToStore.userCrossSigningKeys[userId] = Triple(masterKey, selfSigningKey, userSigningKey) + userDataToStore.userCrossSigningKeys[userId] = CryptoCrossSigningKeys( + masterKey = masterKey, + selfSigningKey = selfSigningKey, + userSigningKey = userSigningKey + ) } cryptoStore.storeUserDataToStore(userDataToStore) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 92a92ab36a..1a7f4a5320 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo @@ -235,9 +236,7 @@ internal interface IMXCryptoStore { fun storeUserCrossSigningKeys( userId: String, - masterKey: CryptoCrossSigningKey?, - selfSigningKey: CryptoCrossSigningKey?, - userSigningKey: CryptoCrossSigningKey? + cryptoCrossSigningKeys: CryptoCrossSigningKeys ) /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt index 05afc75e5a..d4b8308650 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.crypto.store -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo internal data class UserDataToStore( val userDevices: MutableMap> = mutableMapOf(), - val userCrossSigningKeys: MutableMap> = mutableMapOf(), + val userCrossSigningKeys: MutableMap = mutableMapOf(), ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 83ff960d53..06ae2c00b1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -33,7 +33,7 @@ import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo @@ -332,25 +332,21 @@ internal class RealmCryptoStore @Inject constructor( override fun storeUserCrossSigningKeys( userId: String, - masterKey: CryptoCrossSigningKey?, - selfSigningKey: CryptoCrossSigningKey?, - userSigningKey: CryptoCrossSigningKey? + cryptoCrossSigningKeys: CryptoCrossSigningKeys, ) { doRealmTransaction("storeUserCrossSigningKeys", realmConfiguration) { realm -> - storeUserCrossSigningKeys(realm, userId, masterKey, selfSigningKey, userSigningKey) + storeUserCrossSigningKeys(realm, userId, cryptoCrossSigningKeys) } } private fun storeUserCrossSigningKeys( realm: Realm, userId: String, - masterKey: CryptoCrossSigningKey?, - selfSigningKey: CryptoCrossSigningKey?, - userSigningKey: CryptoCrossSigningKey? + keys: CryptoCrossSigningKeys, ) { UserEntity.getOrCreate(realm, userId) .let { userEntity -> - if (masterKey == null || selfSigningKey == null) { + if (keys.masterKey == null || keys.selfSigningKey == null) { // The user has disabled cross signing? userEntity.crossSigningInfoEntity?.deleteOnCascade() userEntity.crossSigningInfoEntity = null @@ -359,11 +355,11 @@ internal class RealmCryptoStore @Inject constructor( CrossSigningInfoEntity.getOrCreate(realm, userId).let { signingInfo -> // What should we do if we detect a change of the keys? val existingMaster = signingInfo.getMasterKey() - if (existingMaster != null && existingMaster.publicKeyBase64 == masterKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingMaster, masterKey) + if (existingMaster != null && existingMaster.publicKeyBase64 == keys.masterKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingMaster, keys.masterKey) } else { Timber.d("## CrossSigning MSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(masterKey) + val keyEntity = crossSigningKeysMapper.map(keys.masterKey) signingInfo.setMasterKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -378,11 +374,11 @@ internal class RealmCryptoStore @Inject constructor( } val existingSelfSigned = signingInfo.getSelfSignedKey() - if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == selfSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingSelfSigned, selfSigningKey) + if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == keys.selfSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingSelfSigned, keys.selfSigningKey) } else { Timber.d("## CrossSigning SSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(selfSigningKey) + val keyEntity = crossSigningKeysMapper.map(keys.selfSigningKey) signingInfo.setSelfSignedKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -394,13 +390,13 @@ internal class RealmCryptoStore @Inject constructor( } // Only for me - if (userSigningKey != null) { + if (keys.userSigningKey != null) { val existingUSK = signingInfo.getUserSigningKey() - if (existingUSK != null && existingUSK.publicKeyBase64 == userSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingUSK, userSigningKey) + if (existingUSK != null && existingUSK.publicKeyBase64 == keys.userSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingUSK, keys.userSigningKey) } else { Timber.d("## CrossSigning USK change for $userId") - val keyEntity = crossSigningKeysMapper.map(userSigningKey) + val keyEntity = crossSigningKeysMapper.map(keys.userSigningKey) signingInfo.setUserSignedKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -1862,7 +1858,7 @@ internal class RealmCryptoStore @Inject constructor( storeUserDevices(realm, it.key, it.value) } userDataToStore.userCrossSigningKeys.forEach { - storeUserCrossSigningKeys(realm, it.key, it.value.first, it.value.second, it.value.third) + storeUserCrossSigningKeys(realm, it.key, it.value) } } } From 06f3c1101042500973c1999f8b9ae0f97a42332e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 16:43:09 +0100 Subject: [PATCH 145/246] Changelog --- changelog.d/7879.bugfix | 1 + .../matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 changelog.d/7879.bugfix diff --git a/changelog.d/7879.bugfix b/changelog.d/7879.bugfix new file mode 100644 index 0000000000..be828ec2cc --- /dev/null +++ b/changelog.d/7879.bugfix @@ -0,0 +1 @@ +Reduce number of crypto database transactions when handling the sync response diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 1a7f4a5320..4ffd93875b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -22,7 +22,6 @@ import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo From 92d048f45a491e4dfe81d7a19b097eedfa7e722a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Jan 2023 18:09:38 +0100 Subject: [PATCH 146/246] Update replied event when it's updated Rebased and squashed. Authors: Claire and Ganfra --- changelog.d/5546.bugfix | 1 + .../sdk/api/session/events/model/Event.kt | 35 ++++++- .../room/send/LocalEchoEventFactory.kt | 46 ++++++--- .../session/room/timeline/DefaultTimeline.kt | 3 + .../room/timeline/DefaultTimelineService.kt | 3 + .../room/timeline/LoadTimelineStrategy.kt | 22 +++++ .../session/room/timeline/TimelineChunk.kt | 93 ++++++++++++------ .../decorator/TimelineEventDecorator.kt | 42 ++++++++ .../timeline/decorator/UiEchoDecorator.kt | 27 ++++++ .../decorator/UpdatedReplyDecorator.kt | 95 +++++++++++++++++++ 10 files changed, 323 insertions(+), 44 deletions(-) create mode 100644 changelog.d/5546.bugfix create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/TimelineEventDecorator.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UiEchoDecorator.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UpdatedReplyDecorator.kt diff --git a/changelog.d/5546.bugfix b/changelog.d/5546.bugfix new file mode 100644 index 0000000000..a3ff48a4a2 --- /dev/null +++ b/changelog.d/5546.bugfix @@ -0,0 +1 @@ +ReplyTo are not updated if the original message is edited or deleted. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 9b5f4ac19f..9a928c61fb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -126,8 +126,37 @@ data class Event( /** * Copy all fields, including transient fields. */ - fun copyAll(): Event { - return copy().also { + + fun copyAll( + type: String? = this.type, + eventId: String? = this.eventId, + content: Content? = this.content, + prevContent: Content? = this.prevContent, + originServerTs: Long? = this.originServerTs, + senderId: String? = this.senderId, + stateKey: String? = this.stateKey, + roomId: String? = this.roomId, + unsignedData: UnsignedData? = this.unsignedData, + redacts: String? = this.redacts, + mxDecryptionResult: OlmDecryptionResult? = this.mxDecryptionResult, + mCryptoError: MXCryptoError.ErrorType? = this.mCryptoError, + mCryptoErrorReason: String? = this.mCryptoErrorReason, + sendState: SendState = this.sendState, + ageLocalTs: Long? = this.ageLocalTs, + threadDetails: ThreadDetails? = this.threadDetails, + ): Event { + return copy( + type = type, + eventId = eventId, + content = content, + prevContent = prevContent, + originServerTs = originServerTs, + senderId = senderId, + stateKey = stateKey, + roomId = roomId, + unsignedData = unsignedData, + redacts = redacts + ).also { it.mxDecryptionResult = mxDecryptionResult it.mCryptoError = mCryptoError it.mCryptoErrorReason = mCryptoErrorReason @@ -429,7 +458,7 @@ fun Event.isReplyRenderedInThread(): Boolean { return isReply() && getRelationContent()?.shouldRenderInThread() == true } -fun Event.isThread(): Boolean = getRelationContentForType(RelationType.THREAD)?.eventId != null +fun Event.isThread(): Boolean = getRootThreadEventId() != null fun Event.getRootThreadEventId(): String? = getRelationContentForType(RelationType.THREAD)?.eventId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 8be6b26249..d974c597ac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -597,26 +597,22 @@ internal class LocalEchoEventFactory @Inject constructor( return clock.epochMillis() } - /** - * Creates a reply to a regular timeline Event or a thread Event if needed. - */ - fun createReplyTextEvent( - roomId: String, + fun createReplyTextContent( eventReplied: TimelineEvent, replyText: CharSequence, replyTextFormatted: CharSequence?, autoMarkdown: Boolean, rootThreadEventId: String? = null, showInThread: Boolean, - additionalContent: Content? = null - ): Event? { + isRedactedEvent: Boolean = false + ): MessageContent? { // Fallbacks and event representation // TODO Add error/warning logs when any of this is null val permalink = permalinkFactory.createPermalink(eventReplied.root, false) ?: return null val userId = eventReplied.root.senderId ?: return null val userLink = permalinkFactory.createPermalink(userId, false) ?: return null - val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply()) + val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply(), isRedactedEvent) // As we always supply formatted body for replies we should force the MarkdownParser to produce html. val finalReplyTextFormatted = replyTextFormatted?.toString() ?: markdownParser.parse(replyText, force = true, advanced = autoMarkdown).takeFormatted() @@ -635,7 +631,7 @@ internal class LocalEchoEventFactory @Inject constructor( val replyFallback = buildReplyFallback(body, userId, replyText.toString()) val eventId = eventReplied.root.eventId ?: return null - val content = MessageTextContent( + return MessageTextContent( msgType = MessageType.MSGTYPE_TEXT, format = MessageFormat.FORMAT_MATRIX_HTML, body = replyFallback, @@ -646,7 +642,25 @@ internal class LocalEchoEventFactory @Inject constructor( showInThread = showInThread ) ) - return createMessageEvent(roomId, content, additionalContent) + } + + /** + * Creates a reply to a regular timeline Event or a thread Event if needed. + */ + fun createReplyTextEvent( + roomId: String, + eventReplied: TimelineEvent, + replyText: CharSequence, + replyTextFormatted: CharSequence?, + autoMarkdown: Boolean, + rootThreadEventId: String? = null, + showInThread: Boolean, + additionalContent: Content? = null, + ): Event? { + val content = createReplyTextContent(eventReplied, replyText, replyTextFormatted, autoMarkdown, rootThreadEventId, showInThread) + return content?.let { + createMessageEvent(roomId, it, additionalContent) + } } private fun generateThreadRelationContent(rootThreadEventId: String) = @@ -715,7 +729,7 @@ internal class LocalEchoEventFactory @Inject constructor( * In case of an edit of a reply the last content is not * himself a reply, but it will contain the fallbacks, so we have to trim them. */ - private fun bodyForReply(content: MessageContent?, isReply: Boolean): TextContent { + fun bodyForReply(content: MessageContent?, isReply: Boolean, isRedactedEvent: Boolean = false): TextContent { when (content?.msgType) { MessageType.MSGTYPE_EMOTE, MessageType.MSGTYPE_TEXT, @@ -724,7 +738,9 @@ internal class LocalEchoEventFactory @Inject constructor( if (content is MessageContentWithFormattedBody) { formattedText = content.matrixFormattedBody } - return if (isReply) { + return if (isRedactedEvent) { + TextContent("message removed.") + } else if (isReply) { TextContent(content.body, formattedText).removeInReplyFallbacks() } else { TextContent(content.body, formattedText) @@ -738,7 +754,11 @@ internal class LocalEchoEventFactory @Inject constructor( MessageType.MSGTYPE_POLL_START -> { return TextContent((content as? MessagePollContent)?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: "") } - else -> return TextContent(content?.body ?: "") + else -> { + return if (isRedactedEvent) { + TextContent("message removed.") + } else TextContent(content?.body ?: "") + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 0854cc5cf4..3ce8ea658d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -42,6 +42,7 @@ import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.sync.handler.room.ReadReceiptHandler import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler @@ -63,6 +64,7 @@ internal class DefaultTimeline( private val settings: TimelineSettings, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val clock: Clock, + localEchoEventFactory: LocalEchoEventFactory, stateEventDataSource: StateEventDataSource, paginationTask: PaginationTask, getEventTask: GetContextOfEventTask, @@ -114,6 +116,7 @@ internal class DefaultTimeline( onNewTimelineEvents = this::onNewTimelineEvents, stateEventDataSource = stateEventDataSource, matrixCoroutineDispatchers = coroutineDispatchers, + localEchoEventFactory = localEchoEventFactory ) private var strategy: LoadTimelineStrategy = buildStrategy(LoadTimelineStrategy.Mode.Live) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt index b1a3d51b36..13852a2bce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt @@ -32,6 +32,7 @@ import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.sync.handler.room.ReadReceiptHandler import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler @@ -55,6 +56,7 @@ internal class DefaultTimelineService @AssistedInject constructor( private val timelineEventDataSource: TimelineEventDataSource, private val clock: Clock, private val stateEventDataSource: StateEventDataSource, + private val localEchoEventFactory: LocalEchoEventFactory ) : TimelineService { @AssistedFactory @@ -82,6 +84,7 @@ internal class DefaultTimelineService @AssistedInject constructor( lightweightSettingsStorage = lightweightSettingsStorage, clock = clock, stateEventDataSource = stateEventDataSource, + localEchoEventFactory = localEchoEventFactory ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index d81a115676..9faf301fe0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -43,7 +43,12 @@ import org.matrix.android.sdk.internal.database.query.findAllIncludingEvents import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfThread import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource +import org.matrix.android.sdk.internal.session.room.timeline.decorator.TimelineEventDecorator +import org.matrix.android.sdk.internal.session.room.timeline.decorator.TimelineEventDecoratorChain +import org.matrix.android.sdk.internal.session.room.timeline.decorator.UiEchoDecorator +import org.matrix.android.sdk.internal.session.room.timeline.decorator.UpdatedReplyDecorator import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber @@ -106,6 +111,7 @@ internal class LoadTimelineStrategy constructor( val onNewTimelineEvents: (List) -> Unit, val stateEventDataSource: StateEventDataSource, val matrixCoroutineDispatchers: MatrixCoroutineDispatchers, + val localEchoEventFactory: LocalEchoEventFactory ) private var getContextLatch: CompletableDeferred? = null @@ -323,6 +329,19 @@ internal class LoadTimelineStrategy constructor( } private fun RealmResults.createTimelineChunk(): TimelineChunk? { + fun createTimelineEventDecorator(): TimelineEventDecorator { + val decorators = listOf( + UiEchoDecorator(uiEchoManager), + UpdatedReplyDecorator( + realm = dependencies.realm, + roomId = roomId, + localEchoEventFactory = dependencies.localEchoEventFactory, + timelineEventMapper = dependencies.timelineEventMapper + ) + ) + return TimelineEventDecoratorChain(decorators) + } + return firstOrNull()?.let { return TimelineChunk( chunkEntity = it, @@ -341,6 +360,9 @@ internal class LoadTimelineStrategy constructor( initialEventId = mode.originEventId(), onBuiltEvents = dependencies.onEventsUpdated, onEventsDeleted = dependencies.onEventsDeleted, + realm = dependencies.realm, + localEchoEventFactory = dependencies.localEchoEventFactory, + decorator = createTimelineEventDecorator() ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 7fa36969b1..c9785e7ea1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room.timeline import io.realm.OrderedCollectionChangeSet import io.realm.OrderedRealmCollectionChangeListener +import io.realm.Realm import io.realm.RealmConfiguration import io.realm.RealmObjectChangeListener import io.realm.RealmQuery @@ -27,9 +28,11 @@ import kotlinx.coroutines.CompletableDeferred import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.isReply import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.api.session.room.timeline.getRelationContent import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.EventMapper import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper @@ -39,10 +42,13 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields import org.matrix.android.sdk.internal.session.room.relation.threads.DefaultFetchThreadTimelineTask import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory +import org.matrix.android.sdk.internal.session.room.timeline.decorator.TimelineEventDecorator import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler import timber.log.Timber import java.util.Collections import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicReference /** * This is a wrapper around a ChunkEntity in the database. @@ -66,6 +72,9 @@ internal class TimelineChunk( private val initialEventId: String?, private val onBuiltEvents: (Boolean) -> Unit, private val onEventsDeleted: () -> Unit, + private val realm: AtomicReference, + private val decorator: TimelineEventDecorator, + val localEchoEventFactory: LocalEchoEventFactory, ) { private val isLastForward = AtomicBoolean(chunkEntity.isLastForward) @@ -74,6 +83,13 @@ internal class TimelineChunk( private var prevChunkLatch: CompletableDeferred? = null private var nextChunkLatch: CompletableDeferred? = null + /** + Map of eventId -> eventId + The key holds the eventId of the repliedTo event. + The value holds a set of eventIds of all events replying to this event. + */ + private val repliedEventsMap = HashMap>() + private val chunkObjectListener = RealmObjectChangeListener { _, changeSet -> if (changeSet == null) return@RealmObjectChangeListener if (changeSet.isDeleted.orFalse()) { @@ -353,9 +369,6 @@ internal class TimelineChunk( timelineEvents .mapIndexed { index, timelineEventEntity -> val timelineEvent = timelineEventEntity.buildAndDecryptIfNeeded() - if (timelineEvent.root.type == EventType.STATE_ROOM_CREATE) { - isLastBackward.set(true) - } if (direction == Timeline.Direction.FORWARDS) { builtEventsIndexes[timelineEvent.eventId] = index builtEvents.add(index, timelineEvent) @@ -394,26 +407,45 @@ internal class TimelineChunk( } private fun TimelineEventEntity.buildAndDecryptIfNeeded(): TimelineEvent { - val timelineEvent = buildTimelineEvent(this) - val transactionId = timelineEvent.root.unsignedData?.transactionId - uiEchoManager?.onSyncedEvent(transactionId) - if (timelineEvent.isEncrypted() && - timelineEvent.root.mxDecryptionResult == null) { - timelineEvent.root.eventId?.also { eventDecryptor.requestDecryption(TimelineEventDecryptor.DecryptionRequest(timelineEvent.root, timelineId)) } + /** + * Makes sure to update some internal state after a TimelineEvent is built. + */ + fun processTimelineEvent(timelineEvent: TimelineEvent) { + if (timelineEvent.root.type == EventType.STATE_ROOM_CREATE) { + isLastBackward.set(true) + } else if (timelineEvent.root.isReply()) { + val relatesEventId = timelineEvent.getRelationContent()?.inReplyTo?.eventId + if (relatesEventId != null) { + val relatedEvents = repliedEventsMap.getOrPut(relatesEventId) { mutableSetOf() } + relatedEvents.add(timelineEvent.eventId) + } + } + val transactionId = timelineEvent.root.unsignedData?.transactionId + uiEchoManager?.onSyncedEvent(transactionId) } - if (!timelineEvent.isEncrypted() && !lightweightSettingsStorage.areThreadMessagesEnabled()) { - // Thread aware for not encrypted events - timelineEvent.root.eventId?.also { eventDecryptor.requestDecryption(TimelineEventDecryptor.DecryptionRequest(timelineEvent.root, timelineId)) } + + fun decryptIfNeeded(timelineEvent: TimelineEvent) { + if (timelineEvent.isEncrypted() && + timelineEvent.root.mxDecryptionResult == null) { + timelineEvent.root.eventId?.also { eventDecryptor.requestDecryption(TimelineEventDecryptor.DecryptionRequest(timelineEvent.root, timelineId)) } + } + if (!timelineEvent.isEncrypted() && !lightweightSettingsStorage.areThreadMessagesEnabled()) { + // Thread aware for not encrypted events + timelineEvent.root.eventId?.also { eventDecryptor.requestDecryption(TimelineEventDecryptor.DecryptionRequest(timelineEvent.root, timelineId)) } + } + } + + return buildTimelineEvent(this).also { timelineEvent -> + decryptIfNeeded(timelineEvent) + processTimelineEvent(timelineEvent) } - return timelineEvent } private fun buildTimelineEvent(eventEntity: TimelineEventEntity) = timelineEventMapper.map( timelineEventEntity = eventEntity, buildReadReceipts = timelineSettings.buildReadReceipts - ).let { - // eventually enhance with ui echo? - (uiEchoManager?.decorateEventWithReactionUiEcho(it) ?: it) + ).let { timelineEvent -> + decorator.decorate(timelineEvent) } /** @@ -493,13 +525,9 @@ internal class TimelineChunk( if (!validateInsertion(range, results)) continue val newItems = results .subList(range.startIndex, range.startIndex + range.length) - .map { it.buildAndDecryptIfNeeded() } - builtEventsIndexes.entries.filter { it.value >= range.startIndex }.forEach { it.setValue(it.value + range.length) } - newItems.mapIndexed { index, timelineEvent -> - if (timelineEvent.root.type == EventType.STATE_ROOM_CREATE) { - isLastBackward.set(true) - } + newItems.mapIndexed { index, timelineEventEntity -> + val timelineEvent = timelineEventEntity.buildAndDecryptIfNeeded() val correctedIndex = range.startIndex + index builtEvents.add(correctedIndex, timelineEvent) builtEventsIndexes[timelineEvent.eventId] = correctedIndex @@ -509,11 +537,17 @@ internal class TimelineChunk( for (range in modifications) { for (modificationIndex in (range.startIndex until range.startIndex + range.length)) { val updatedEntity = results[modificationIndex] ?: continue - val builtEventIndex = builtEventsIndexes[updatedEntity.eventId] ?: continue - try { - builtEvents[builtEventIndex] = updatedEntity.buildAndDecryptIfNeeded() - } catch (failure: Throwable) { - Timber.v("Fail to update items at index: $modificationIndex") + val updatedEventId = updatedEntity.eventId + val repliesOfUpdatedEvent = repliedEventsMap.getOrElse(updatedEventId) { emptySet() }.mapNotNull { eventId -> + results.where().equalTo(TimelineEventEntityFields.EVENT_ID, eventId).findFirst() + } + repliesOfUpdatedEvent.plus(updatedEntity).forEach { entityToRebuild -> + val builtEventIndex = builtEventsIndexes[entityToRebuild.eventId] ?: return@forEach + try { + builtEvents[builtEventIndex] = entityToRebuild.buildAndDecryptIfNeeded() + } catch (failure: Throwable) { + Timber.v("Fail to update items at index: $modificationIndex") + } } } } @@ -580,7 +614,10 @@ internal class TimelineChunk( lightweightSettingsStorage = lightweightSettingsStorage, initialEventId = null, onBuiltEvents = this.onBuiltEvents, - onEventsDeleted = this.onEventsDeleted + onEventsDeleted = this.onEventsDeleted, + decorator = this.decorator, + realm = realm, + localEchoEventFactory = localEchoEventFactory ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/TimelineEventDecorator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/TimelineEventDecorator.kt new file mode 100644 index 0000000000..261407ba5f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/TimelineEventDecorator.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.timeline.decorator + +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent + +/** + * This interface can be used to make a copy of a TimelineEvent with new data, before the event is posted to the timeline. + */ +internal fun interface TimelineEventDecorator { + fun decorate(timelineEvent: TimelineEvent): TimelineEvent +} + +/** + * This is an implementation of [TimelineEventDecorator] which chains calls to decorators. + */ +internal class TimelineEventDecoratorChain(private val decorators: List) : TimelineEventDecorator { + + override fun decorate(timelineEvent: TimelineEvent): TimelineEvent { + var decorated = timelineEvent + val iterator = decorators.iterator() + while (iterator.hasNext()) { + val decorator = iterator.next() + decorated = decorator.decorate(decorated) + } + return decorated + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UiEchoDecorator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UiEchoDecorator.kt new file mode 100644 index 0000000000..778a9d27d9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UiEchoDecorator.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.timeline.decorator + +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.internal.session.room.timeline.UIEchoManager + +internal class UiEchoDecorator(private val uiEchoManager: UIEchoManager?) : TimelineEventDecorator { + + override fun decorate(timelineEvent: TimelineEvent): TimelineEvent { + return uiEchoManager?.decorateEventWithReactionUiEcho(timelineEvent) ?: timelineEvent + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UpdatedReplyDecorator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UpdatedReplyDecorator.kt new file mode 100644 index 0000000000..2b12fe814c --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/decorator/UpdatedReplyDecorator.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.timeline.decorator + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.isThread +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent +import org.matrix.android.sdk.api.session.room.timeline.getRelationContent +import org.matrix.android.sdk.api.session.room.timeline.isReply +import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper +import org.matrix.android.sdk.internal.database.mapper.asDomain +import org.matrix.android.sdk.internal.database.model.TimelineEventEntity +import org.matrix.android.sdk.internal.database.query.where +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory +import java.util.concurrent.atomic.AtomicReference + +internal class UpdatedReplyDecorator( + private val realm: AtomicReference, + private val roomId: String, + private val localEchoEventFactory: LocalEchoEventFactory, + private val timelineEventMapper: TimelineEventMapper, +) : TimelineEventDecorator { + + override fun decorate(timelineEvent: TimelineEvent): TimelineEvent { + return if (timelineEvent.isReply() && !timelineEvent.root.isThread()) { + val newRepliedEvent = createNewRepliedEvent(timelineEvent) ?: return timelineEvent + timelineEvent.copy(root = newRepliedEvent) + } else { + timelineEvent + } + } + + private fun createNewRepliedEvent(currentTimelineEvent: TimelineEvent): Event? { + val relatesEventId = currentTimelineEvent.getRelationContent()?.inReplyTo?.eventId ?: return null + val timelineEventEntity = TimelineEventEntity.where( + realm.get(), + roomId, + relatesEventId + ).findFirst() ?: return null + + val isRedactedEvent = timelineEventEntity.root?.asDomain()?.isRedacted() ?: false + + val replyText = localEchoEventFactory + .bodyForReply(currentTimelineEvent.getLastMessageContent(), true).formattedText ?: "" + + val newContent = localEchoEventFactory.createReplyTextContent( + timelineEventMapper.map(timelineEventEntity), + replyText, + null, + false, + showInThread = false, + isRedactedEvent = isRedactedEvent + ).toContent() + + val decryptionResultToSet = currentTimelineEvent.root.mxDecryptionResult?.copy( + payload = mapOf( + "content" to newContent, + "type" to EventType.MESSAGE + ) + ) + + val contentToSet = if (currentTimelineEvent.isEncrypted()) { + // Keep encrypted content as is + currentTimelineEvent.root.content + } else { + // Use new content + newContent + } + + return currentTimelineEvent.root.copyAll( + content = contentToSet, + mxDecryptionResult = decryptionResultToSet, + mCryptoError = null, + mCryptoErrorReason = null + ) + } +} From 437b93cc18751777e92f7a249dd67c93460382e0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Jan 2023 11:35:04 +0100 Subject: [PATCH 147/246] Add some doc --- .../internal/crypto/store/IMXCryptoStore.kt | 19 +++++++++++++++++++ .../internal/crypto/store/UserDataToStore.kt | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 4ffd93875b..a74a7f2906 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -48,7 +48,19 @@ import org.matrix.olm.OlmOutboundGroupSession */ internal interface IMXCryptoStore { + /** + * Notify the store that a sync response treatment is starting. + * Impacted methods: + * - [setShouldShareHistory] + * - [setShouldEncryptForInvitedMembers] + * @See [onSyncCompleted] to notify that the treatment is over. + */ fun onSyncWillProcess() + + /** + * Notify the store that the sync treatment response is finished. + * The store will save all aggregated data. + */ fun onSyncCompleted() /** @@ -291,6 +303,9 @@ internal interface IMXCryptoStore { fun shouldEncryptForInvitedMembers(roomId: String): Boolean + /** + * The data is not stored immediately, this MUST be call during a sync response treatment. + */ fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) fun shouldShareHistory(roomId: String): Boolean @@ -298,6 +313,7 @@ internal interface IMXCryptoStore { /** * Sets a boolean flag that will determine whether or not room history (existing inbound sessions) * will be shared to new user invites. + * The data is not stored immediately, this MUST be call during a sync response treatment. * * @param roomId the room id * @param shouldShareHistory The boolean flag @@ -582,5 +598,8 @@ internal interface IMXCryptoStore { fun tidyUpDataBase() fun getOutgoingRoomKeyRequests(inStates: Set): List + /** + * Store a bunch of data related to the users. @See [UserDataToStore]. + */ fun storeUserDataToStore(userDataToStore: UserDataToStore) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt index d4b8308650..89cbe4e826 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt @@ -20,6 +20,12 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigning import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo internal data class UserDataToStore( + /** + * Map of userId -> (Map of deviceId -> [CryptoDeviceInfo]). + */ val userDevices: MutableMap> = mutableMapOf(), + /** + * Map of userId -> [CryptoCrossSigningKeys]. + */ val userCrossSigningKeys: MutableMap = mutableMapOf(), ) From 0d5b6efd5cbb681e54de0c13c296c11ee6f5cc31 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 14:56:41 +0100 Subject: [PATCH 148/246] Use latest version of lint --- gradle.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gradle.properties b/gradle.properties index 2c999af35d..ea70ad5e51 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,3 +39,7 @@ signing.element.keyPassword=Secret signing.element.nightly.storePassword=Secret signing.element.nightly.keyId=Secret signing.element.nightly.keyPassword=Secret + +# Customise the Lint version to use a more recent version than the one bundled with AGP +# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html +android.experimental.lint.version=8.0.0-alpha10 From 36b1c12b81358fbc4a0614c25de090d93f179708 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 15:04:42 +0100 Subject: [PATCH 149/246] Fix error reported for usage of some methods from API 33 --- .../home/NotificationPermissionManager.kt | 16 +++++----------- .../troubleshoot/TestSystemSettings.kt | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/NotificationPermissionManager.kt b/vector/src/main/java/im/vector/app/features/home/NotificationPermissionManager.kt index 33ba1be02b..4f585becca 100644 --- a/vector/src/main/java/im/vector/app/features/home/NotificationPermissionManager.kt +++ b/vector/src/main/java/im/vector/app/features/home/NotificationPermissionManager.kt @@ -21,7 +21,6 @@ import android.app.Activity import android.content.pm.PackageManager import android.os.Build import androidx.activity.result.ActivityResultLauncher -import androidx.annotation.ChecksSdkIntAtLeast import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import im.vector.app.R @@ -35,17 +34,12 @@ class NotificationPermissionManager @Inject constructor( private val vectorPreferences: VectorPreferences, ) { - @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU) + @RequiresApi(Build.VERSION_CODES.TIRAMISU) fun isPermissionGranted(activity: Activity): Boolean { - return if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) { - ContextCompat.checkSelfPermission( - activity, - Manifest.permission.POST_NOTIFICATIONS - ) == PackageManager.PERMISSION_GRANTED - } else { - // No notification permission management before API 33. - true - } + return ContextCompat.checkSelfPermission( + activity, + Manifest.permission.POST_NOTIFICATIONS + ) == PackageManager.PERMISSION_GRANTED } fun eventuallyRequestPermission( diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt index 0f362d5019..589edecad9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt @@ -15,12 +15,14 @@ */ package im.vector.app.features.settings.troubleshoot +import android.os.Build import androidx.core.app.NotificationManagerCompat import androidx.fragment.app.FragmentActivity import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.startNotificationSettingsIntent import im.vector.app.features.home.NotificationPermissionManager +import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider import javax.inject.Inject /** @@ -30,6 +32,7 @@ import javax.inject.Inject class TestSystemSettings @Inject constructor( private val context: FragmentActivity, private val stringProvider: StringProvider, + private val sdkIntProvider: BuildVersionSdkIntProvider, private val notificationPermissionManager: NotificationPermissionManager, ) : TroubleshootTest(R.string.settings_troubleshoot_test_system_settings_title) { @@ -39,14 +42,7 @@ class TestSystemSettings @Inject constructor( quickFix = null status = TestStatus.SUCCESS } else { - if (notificationPermissionManager.isPermissionGranted(context)) { - description = stringProvider.getString(R.string.settings_troubleshoot_test_system_settings_failed) - quickFix = object : TroubleshootQuickFix(R.string.open_settings) { - override fun doFix() { - startNotificationSettingsIntent(context, testParameters.activityResultLauncher) - } - } - } else { + if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU) && notificationPermissionManager.isPermissionGranted(context).not()) { // In this case, we can ask for user permission description = stringProvider.getString(R.string.settings_troubleshoot_test_system_settings_permission_failed) quickFix = object : TroubleshootQuickFix(R.string.grant_permission) { @@ -54,6 +50,13 @@ class TestSystemSettings @Inject constructor( notificationPermissionManager.askPermission(testParameters.permissionResultLauncher) } } + } else { + description = stringProvider.getString(R.string.settings_troubleshoot_test_system_settings_failed) + quickFix = object : TroubleshootQuickFix(R.string.open_settings) { + override fun doFix() { + startNotificationSettingsIntent(context, testParameters.activityResultLauncher) + } + } } status = TestStatus.FAILED } From c8595df658d5a28ec63d69cf87bd6447ad01eeff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:05:54 +0000 Subject: [PATCH 150/246] Bump firebase-messaging from 23.1.0 to 23.1.1 Bumps firebase-messaging from 23.1.0 to 23.1.1. --- updated-dependencies: - dependency-name: com.google.firebase:firebase-messaging dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- vector-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 4e954962fc..6cadb9feef 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -364,7 +364,7 @@ dependencies { gplayImplementation "com.google.android.gms:play-services-location:21.0.1" // UnifiedPush gplay flavor only - gplayImplementation('com.google.firebase:firebase-messaging:23.1.0') { + gplayImplementation('com.google.firebase:firebase-messaging:23.1.1') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' From 12ccf13171bbb54e026e9e044f23090bcf84a72e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 15:54:23 +0100 Subject: [PATCH 151/246] Use Firebase BOM --- dependencies.gradle | 3 +++ vector-app/build.gradle | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index b81c1c2017..d8a97ba0b1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -11,6 +11,7 @@ def gradle = "7.3.1" def kotlin = "1.7.22" def kotlinCoroutines = "1.6.4" def dagger = "2.44.2" +def firebaseBom = "31.1.1" def appDistribution = "16.0.0-beta05" def retrofit = "2.9.0" def markwon = "4.6.2" @@ -80,6 +81,8 @@ ext.libs = [ ], google : [ 'material' : "com.google.android.material:material:1.7.0", + 'firebaseBom' : "com.google.firebase:firebase-bom:$firebaseBom", + 'messaging' : "com.google.firebase:firebase-messaging", 'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution", 'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution", // Phone number https://github.com/google/libphonenumber diff --git a/vector-app/build.gradle b/vector-app/build.gradle index 6cadb9feef..e157f0704a 100644 --- a/vector-app/build.gradle +++ b/vector-app/build.gradle @@ -364,7 +364,8 @@ dependencies { gplayImplementation "com.google.android.gms:play-services-location:21.0.1" // UnifiedPush gplay flavor only - gplayImplementation('com.google.firebase:firebase-messaging:23.1.1') { + gplayImplementation platform(libs.google.firebaseBom) + gplayImplementation(libs.google.messaging) { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' From 01429b352af7616f868b9dc9588d3847360ac3c4 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 27 Dec 2022 16:30:05 +0100 Subject: [PATCH 152/246] Fix inactivity status when last seen timestamp is null --- .../settings/devices/DevicesViewModel.kt | 2 +- .../v2/GetDeviceFullInfoListUseCase.kt | 2 +- .../list/CheckIfSessionIsInactiveUseCase.kt | 14 +++--- .../v2/overview/GetDeviceFullInfoUseCase.kt | 2 +- .../CheckIfSessionIsInactiveUseCaseTest.kt | 50 ++++++++++++++----- 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index e779948b41..cbc02ba0f0 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -142,7 +142,7 @@ class DevicesViewModel @AssistedInject constructor( .map { deviceInfo -> val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId } val trustLevelForShield = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) - val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0) + val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs) DeviceFullInfo(deviceInfo, cryptoDeviceInfo, trustLevelForShield, isInactive) } } 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 6adb33d5ab..1ae7d8836f 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 @@ -75,7 +75,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor( .map { deviceInfo -> val cryptoDeviceInfo = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId } val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) - val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs ?: 0) + val isInactive = checkIfSessionIsInactiveUseCase.execute(deviceInfo.lastSeenTs) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoDeviceInfo?.deviceId val deviceExtendedInfo = parseDeviceUserAgentUseCase.execute(deviceInfo.getBestLastSeenUserAgent()) val matrixClientInfo = deviceInfo.deviceId diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCase.kt index 8991ad1e3d..f3670793bd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCase.kt @@ -24,11 +24,13 @@ class CheckIfSessionIsInactiveUseCase @Inject constructor( private val clock: Clock, ) { - fun execute(lastSeenTs: Long): Boolean { - // In case of the server doesn't send the last seen date. - if (lastSeenTs == 0L) return true - - val diffMilliseconds = clock.epochMillis() - lastSeenTs - return diffMilliseconds >= TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) + fun execute(lastSeenTsMillis: Long?): Boolean { + return if (lastSeenTsMillis == null || lastSeenTsMillis <= 0) { + // in these situations we cannot say anything about the inactivity of the session + false + } else { + val diffMilliseconds = clock.epochMillis() - lastSeenTsMillis + diffMilliseconds >= TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) + } } } 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 140b55a30c..3b67eee780 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 cryptoInfo = cryptoDeviceInfo.getOrNull() val fullInfo = if (info != null && cryptoInfo != null) { val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo) - val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs ?: 0) + val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs) val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoInfo.deviceId val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.getBestLastSeenUserAgent()) val matrixClientInfo = info.deviceId diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCaseTest.kt index b7d56a88bf..20291e5ee2 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/list/CheckIfSessionIsInactiveUseCaseTest.kt @@ -17,43 +17,69 @@ package im.vector.app.features.settings.devices.v2.list import im.vector.app.test.fakes.FakeClock -import org.amshove.kluent.shouldBeEqualTo +import org.amshove.kluent.shouldBeFalse +import org.amshove.kluent.shouldBeTrue import org.junit.Test import java.util.concurrent.TimeUnit -private const val A_TIMESTAMP = 1654689143L +private const val A_TIMESTAMP_MILLIS = 1654689143000L class CheckIfSessionIsInactiveUseCaseTest { - private val clock = FakeClock().apply { givenEpoch(A_TIMESTAMP) } + private val clock = FakeClock().apply { givenEpoch(A_TIMESTAMP_MILLIS) } private val checkIfSessionIsInactiveUseCase = CheckIfSessionIsInactiveUseCase(clock) @Test fun `given an old last seen date then session is inactive`() { - val lastSeenDate = A_TIMESTAMP - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) - 1 + val lastSeenDate = A_TIMESTAMP_MILLIS - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) - 1 - checkIfSessionIsInactiveUseCase.execute(lastSeenDate) shouldBeEqualTo true + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeTrue() } @Test fun `given a last seen date equal to the threshold then session is inactive`() { - val lastSeenDate = A_TIMESTAMP - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) + val lastSeenDate = A_TIMESTAMP_MILLIS - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) - checkIfSessionIsInactiveUseCase.execute(lastSeenDate) shouldBeEqualTo true + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeTrue() } @Test fun `given a recent last seen date then session is active`() { - val lastSeenDate = A_TIMESTAMP - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) + 1 + val lastSeenDate = A_TIMESTAMP_MILLIS - TimeUnit.DAYS.toMillis(SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS.toLong()) + 1 - checkIfSessionIsInactiveUseCase.execute(lastSeenDate) shouldBeEqualTo false + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeFalse() } @Test - fun `given a last seen date as zero then session is inactive`() { - // In case of the server doesn't send the last seen date. + fun `given a last seen date as zero then session is not inactive`() { val lastSeenDate = 0L - checkIfSessionIsInactiveUseCase.execute(lastSeenDate) shouldBeEqualTo true + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeFalse() + } + + @Test + fun `given a last seen date as null then session is not inactive`() { + val lastSeenDate = null + + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeFalse() + } + + @Test + fun `given a last seen date as negative then session is not inactive`() { + val lastSeenDate = -3L + + val result = checkIfSessionIsInactiveUseCase.execute(lastSeenDate) + + result.shouldBeFalse() } } From 1af712910f431712a77374702a6064b5c839177e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 27 Dec 2022 16:41:25 +0100 Subject: [PATCH 153/246] Use deviceId as session name when there is no display name --- .../settings/devices/v2/list/OtherSessionsController.kt | 3 ++- .../features/settings/devices/v2/list/SessionInfoView.kt | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt index 5e2549f42a..e85e394681 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt @@ -63,12 +63,13 @@ class OtherSessionsController @Inject constructor( } val drawableColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary) val descriptionDrawable = if (device.isInactive) host.drawableProvider.getDrawable(R.drawable.ic_inactive_sessions, drawableColor) else null + val sessionName = device.deviceInfo.displayName ?: device.deviceInfo.deviceId otherSessionItem { id(device.deviceInfo.deviceId) deviceType(device.deviceExtendedInfo.deviceType) roomEncryptionTrustLevel(device.roomEncryptionTrustLevel) - sessionName(device.deviceInfo.displayName) + sessionName(sessionName) sessionDescription(description) sessionDescriptionDrawable(descriptionDrawable) sessionDescriptionColor(descriptionColor) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt index 5d2daf2941..81a8aae666 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt @@ -62,9 +62,10 @@ class SessionInfoView @JvmOverloads constructor( stringProvider: StringProvider, ) { renderDeviceInfo( - sessionInfoViewState.deviceFullInfo.deviceInfo.displayName.orEmpty(), - sessionInfoViewState.deviceFullInfo.deviceExtendedInfo.deviceType, - stringProvider, + sessionName = sessionInfoViewState.deviceFullInfo.deviceInfo.displayName + ?: sessionInfoViewState.deviceFullInfo.deviceInfo.deviceId.orEmpty(), + deviceType = sessionInfoViewState.deviceFullInfo.deviceExtendedInfo.deviceType, + stringProvider = stringProvider, ) renderVerificationStatus( sessionInfoViewState.deviceFullInfo.roomEncryptionTrustLevel, From 6fdb1216ba5781a61f85baca1188b2e1b53020c3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 27 Dec 2022 17:24:32 +0100 Subject: [PATCH 154/246] Fixing missing session info when there is no crypto info --- .../v2/overview/GetDeviceFullInfoUseCase.kt | 4 +- .../overview/GetDeviceFullInfoUseCaseTest.kt | 47 +++++++++++++++++-- 2 files changed, 46 insertions(+), 5 deletions(-) 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 3b67eee780..445d2309a4 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 @@ -49,10 +49,10 @@ class GetDeviceFullInfoUseCase @Inject constructor( ) { currentSessionCrossSigningInfo, deviceInfo, cryptoDeviceInfo -> val info = deviceInfo.getOrNull() val cryptoInfo = cryptoDeviceInfo.getOrNull() - val fullInfo = if (info != null && cryptoInfo != null) { + val fullInfo = if (info != null) { val roomEncryptionTrustLevel = getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoInfo) val isInactive = checkIfSessionIsInactiveUseCase.execute(info.lastSeenTs) - val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == cryptoInfo.deviceId + val isCurrentDevice = currentSessionCrossSigningInfo.deviceId == info.deviceId val deviceUserAgent = parseDeviceUserAgentUseCase.execute(info.getBestLastSeenUserAgent()) val matrixClientInfo = info.deviceId ?.takeIf { it.isNotEmpty() } 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 2185c295d0..48c5ce74b4 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 @@ -117,6 +117,45 @@ class GetDeviceFullInfoUseCaseTest { } } + @Test + fun `given current session and no crypto info for device when getting device info then the result is correct`() = runTest { + // Given + val currentSessionCrossSigningInfo = givenCurrentSessionCrossSigningInfo() + val deviceInfo = givenADeviceInfo() + val cryptoDeviceInfo = null + val trustLevel = givenTrustLevel(currentSessionCrossSigningInfo, cryptoDeviceInfo) + val isInactive = false + val isCurrentDevice = true + every { checkIfSessionIsInactiveUseCase.execute(any()) } returns isInactive + every { parseDeviceUserAgentUseCase.execute(any()) } returns DeviceExtendedInfo(DeviceType.MOBILE) + val matrixClientInfo = givenAMatrixClientInfo() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData = MutableLiveData(Optional(null)) + fakeActiveSessionHolder.fakeSession.fakeCryptoService.cryptoDeviceInfoWithIdLiveData.givenAsFlow() + + // When + val deviceFullInfo = getDeviceFullInfoUseCase.execute(A_DEVICE_ID).firstOrNull() + + // Then + deviceFullInfo shouldBeEqualTo DeviceFullInfo( + deviceInfo = deviceInfo, + cryptoDeviceInfo = cryptoDeviceInfo, + roomEncryptionTrustLevel = trustLevel, + isInactive = isInactive, + isCurrentDevice = isCurrentDevice, + deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE), + matrixClientInfo = matrixClientInfo, + ) + verify { + fakeActiveSessionHolder.instance.getSafeActiveSession() + getCurrentSessionCrossSigningInfoUseCase.execute() + getEncryptionTrustLevelForDeviceUseCase.execute(currentSessionCrossSigningInfo, cryptoDeviceInfo) + fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() + checkIfSessionIsInactiveUseCase.execute(A_TIMESTAMP) + getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID) + } + } + @Test fun `given current session and no info for device when getting device info then the result is empty`() = runTest { // Given @@ -131,9 +170,11 @@ class GetDeviceFullInfoUseCaseTest { // Then deviceFullInfo.shouldBeNull() - verify { fakeActiveSessionHolder.instance.getSafeActiveSession() } - verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() } - verify { fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() } + verify { + fakeActiveSessionHolder.instance.getSafeActiveSession() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.getMyDevicesInfoLive(A_DEVICE_ID).asFlow() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.getLiveCryptoDeviceInfoWithId(A_DEVICE_ID).asFlow() + } } @Test From fa7766f8a68755b3196c239c76daf17ae035f271 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 27 Dec 2022 17:24:45 +0100 Subject: [PATCH 155/246] Fixing missing device without encryption support in the unverified session list --- .../settings/devices/v2/DevicesViewModel.kt | 40 +++++++++---------- .../settings/devices/v2/DevicesViewState.kt | 10 +++-- .../v2/VectorSettingsDevicesFragment.kt | 12 +++--- .../devices/v2/filter/FilterDevicesUseCase.kt | 4 +- .../devices/v2/DevicesViewModelTest.kt | 23 ++++++----- .../v2/filter/FilterDevicesUseCaseTest.kt | 19 +++++++-- 6 files changed, 64 insertions(+), 44 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt index 232fcd50f7..f2e6b25f32 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewModel.kt @@ -18,7 +18,6 @@ package im.vector.app.features.settings.devices.v2 import android.content.SharedPreferences import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.Success import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -32,10 +31,10 @@ import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsReAuthN import im.vector.app.features.settings.devices.v2.signout.SignoutSessionsUseCase import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase import im.vector.app.features.settings.devices.v2.verification.GetCurrentSessionCrossSigningInfoUseCase +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth import timber.log.Timber @@ -103,27 +102,27 @@ class DevicesViewModel @AssistedInject constructor( } private fun observeDevices() { - getDeviceFullInfoListUseCase.execute( + val allSessionsFlow = getDeviceFullInfoListUseCase.execute( filterType = DeviceManagerFilterType.ALL_SESSIONS, - excludeCurrentDevice = false + excludeCurrentDevice = false, + ) + val unverifiedSessionsFlow = getDeviceFullInfoListUseCase.execute( + filterType = DeviceManagerFilterType.UNVERIFIED, + excludeCurrentDevice = true, + ) + val inactiveSessionsFlow = getDeviceFullInfoListUseCase.execute( + filterType = DeviceManagerFilterType.INACTIVE, + excludeCurrentDevice = true, ) - .execute { async -> - if (async is Success) { - val deviceFullInfoList = async.invoke() - val unverifiedSessionsCount = deviceFullInfoList.count { !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse() } - val inactiveSessionsCount = deviceFullInfoList.count { it.isInactive } - copy( - devices = async, - unverifiedSessionsCount = unverifiedSessionsCount, - inactiveSessionsCount = inactiveSessionsCount, - ) - } else { - copy( - devices = async - ) - } - } + combine(allSessionsFlow, unverifiedSessionsFlow, inactiveSessionsFlow) { allSessions, unverifiedSessions, inactiveSessions -> + DeviceFullInfoList( + allSessions = allSessions, + unverifiedSessionsCount = unverifiedSessions.size, + inactiveSessionsCount = inactiveSessions.size, + ) + } + .execute { async -> copy(devices = async) } } private fun refreshDevicesOnCryptoDevicesChange() { @@ -185,6 +184,7 @@ class DevicesViewModel @AssistedInject constructor( private fun getDeviceIdsOfOtherSessions(state: DevicesViewState): List { val currentDeviceId = state.currentSessionCrossSigningInfo.deviceId return state.devices() + ?.allSessions ?.mapNotNull { fullInfo -> fullInfo.deviceInfo.deviceId.takeUnless { it == currentDeviceId } } .orEmpty() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt index e0531c34dc..75d0f132bb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/DevicesViewState.kt @@ -23,9 +23,13 @@ import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCro data class DevicesViewState( val currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(), - val devices: Async> = Uninitialized, - val unverifiedSessionsCount: Int = 0, - val inactiveSessionsCount: Int = 0, + val devices: Async = Uninitialized, val isLoading: Boolean = false, val isShowingIpAddress: Boolean = false, ) : MavericksState + +data class DeviceFullInfoList( + val allSessions: List, + val unverifiedSessionsCount: Int, + val inactiveSessionsCount: Int, +) 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 15375ef679..f83b00a75e 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 @@ -55,7 +55,6 @@ import im.vector.app.features.settings.devices.v2.signout.BuildConfirmSignoutDia import im.vector.app.features.workers.signout.SignOutUiWorker import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject /** @@ -282,13 +281,15 @@ class VectorSettingsDevicesFragment : override fun invalidate() = withState(viewModel) { state -> if (state.devices is Success) { - val devices = state.devices() + val deviceFullInfoList = state.devices() + val devices = deviceFullInfoList?.allSessions val currentDeviceId = state.currentSessionCrossSigningInfo.deviceId val currentDeviceInfo = devices?.firstOrNull { it.deviceInfo.deviceId == currentDeviceId } - val isCurrentSessionVerified = currentDeviceInfo?.roomEncryptionTrustLevel == RoomEncryptionTrustLevel.Trusted val otherDevices = devices?.filter { it.deviceInfo.deviceId != currentDeviceId } + val inactiveSessionsCount = deviceFullInfoList?.inactiveSessionsCount ?: 0 + val unverifiedSessionsCount = deviceFullInfoList?.unverifiedSessionsCount ?: 0 - renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount, isCurrentSessionVerified) + renderSecurityRecommendations(inactiveSessionsCount, unverifiedSessionsCount) renderCurrentSessionView(currentDeviceInfo, hasOtherDevices = otherDevices?.isNotEmpty().orFalse()) renderOtherSessionsView(otherDevices, state.isShowingIpAddress) } else { @@ -303,9 +304,8 @@ class VectorSettingsDevicesFragment : private fun renderSecurityRecommendations( inactiveSessionsCount: Int, unverifiedSessionsCount: Int, - isCurrentSessionVerified: Boolean, ) { - val isUnverifiedSectionVisible = unverifiedSessionsCount > 0 && isCurrentSessionVerified + val isUnverifiedSectionVisible = unverifiedSessionsCount > 0 val isInactiveSectionVisible = inactiveSessionsCount > 0 if (isUnverifiedSectionVisible.not() && isInactiveSectionVisible.not()) { hideSecurityRecommendations() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt index 8f23fd06cc..b1f23eb510 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt @@ -37,7 +37,9 @@ class FilterDevicesUseCase @Inject constructor() { // when current session is not verified, other session status cannot be trusted DeviceManagerFilterType.VERIFIED -> isCurrentSessionVerified && it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse() // when current session is not verified, other session status cannot be trusted - DeviceManagerFilterType.UNVERIFIED -> isCurrentSessionVerified && !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse() + DeviceManagerFilterType.UNVERIFIED -> + (isCurrentSessionVerified && !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()) || + it.cryptoDeviceInfo == null DeviceManagerFilterType.INACTIVE -> it.isInactive } } 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 524858da77..79c998ff5c 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 @@ -21,6 +21,7 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MavericksTestRule import im.vector.app.core.session.clientinfo.MatrixClientInfoContent import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo +import im.vector.app.features.settings.devices.v2.filter.DeviceManagerFilterType 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 @@ -176,10 +177,7 @@ class DevicesViewModelTest { val viewModelTest = createViewModel().test() // Then - viewModelTest.assertLatestState { - it.devices is Success && it.devices.invoke() == deviceFullInfoList && - it.inactiveSessionsCount == 1 && it.unverifiedSessionsCount == 1 - } + viewModelTest.assertLatestState { it.devices is Success && it.devices.invoke() == deviceFullInfoList } viewModelTest.finish() } @@ -403,7 +401,7 @@ class DevicesViewModelTest { /** * Generate mocked deviceFullInfo list with 1 unverified and inactive + 1 verified and active. */ - private fun givenDeviceFullInfoList(deviceId1: String, deviceId2: String): List { + private fun givenDeviceFullInfoList(deviceId1: String, deviceId2: String): DeviceFullInfoList { val verifiedCryptoDeviceInfo = mockk() every { verifiedCryptoDeviceInfo.trustLevel } returns DeviceTrustLevel(crossSigningVerified = true, locallyVerified = true) val unverifiedCryptoDeviceInfo = mockk() @@ -432,10 +430,15 @@ class DevicesViewModelTest { deviceExtendedInfo = DeviceExtendedInfo(DeviceType.MOBILE), matrixClientInfo = MatrixClientInfoContent(), ) - val deviceFullInfoList = listOf(deviceFullInfo1, deviceFullInfo2) - val deviceFullInfoListFlow = flowOf(deviceFullInfoList) - every { getDeviceFullInfoListUseCase.execute(any(), any()) } returns deviceFullInfoListFlow - return deviceFullInfoList + val devices = listOf(deviceFullInfo1, deviceFullInfo2) + every { getDeviceFullInfoListUseCase.execute(DeviceManagerFilterType.ALL_SESSIONS, any()) } returns flowOf(devices) + every { getDeviceFullInfoListUseCase.execute(DeviceManagerFilterType.UNVERIFIED, any()) } returns flowOf(listOf(deviceFullInfo2)) + every { getDeviceFullInfoListUseCase.execute(DeviceManagerFilterType.INACTIVE, any()) } returns flowOf(listOf(deviceFullInfo1)) + return DeviceFullInfoList( + allSessions = devices, + unverifiedSessionsCount = 1, + inactiveSessionsCount = 1, + ) } private fun givenInitialViewState(deviceId1: String, deviceId2: String): DevicesViewState { @@ -444,8 +447,6 @@ class DevicesViewModelTest { return DevicesViewState( currentSessionCrossSigningInfo = currentSessionCrossSigningInfo, devices = Success(deviceFullInfoList), - unverifiedSessionsCount = 1, - inactiveSessionsCount = 1, isLoading = false, ) } 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 79dff5bc16..2e8a81bf54 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 @@ -22,6 +22,7 @@ import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtende import im.vector.app.features.settings.devices.v2.list.DeviceType import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo import org.amshove.kluent.shouldBeEqualTo +import org.amshove.kluent.shouldContain import org.amshove.kluent.shouldContainAll import org.junit.Test import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel @@ -82,11 +83,22 @@ private val inactiveUnverifiedDevice = DeviceFullInfo( matrixClientInfo = MatrixClientInfoContent(), ) +private val deviceWithoutEncryptionSupport = DeviceFullInfo( + deviceInfo = DeviceInfo(deviceId = "DEVICE_WITHOUT_ENCRYPTION_SUPPORT"), + cryptoDeviceInfo = null, + roomEncryptionTrustLevel = null, + isInactive = false, + isCurrentDevice = false, + deviceExtendedInfo = DeviceExtendedInfo(DeviceType.UNKNOWN), + matrixClientInfo = MatrixClientInfoContent(), +) + private val devices = listOf( activeVerifiedDevice, inactiveVerifiedDevice, activeUnverifiedDevice, inactiveUnverifiedDevice, + deviceWithoutEncryptionSupport, ) class FilterDevicesUseCaseTest { @@ -123,8 +135,8 @@ class FilterDevicesUseCaseTest { val currentSessionCrossSigningInfo = givenCurrentSessionVerified(true) val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.UNVERIFIED, emptyList()) - filteredDeviceList.size shouldBeEqualTo 2 - filteredDeviceList shouldContainAll listOf(activeUnverifiedDevice, inactiveUnverifiedDevice) + filteredDeviceList.size shouldBeEqualTo 3 + filteredDeviceList shouldContainAll listOf(activeUnverifiedDevice, inactiveUnverifiedDevice, deviceWithoutEncryptionSupport) } @Test @@ -132,7 +144,8 @@ class FilterDevicesUseCaseTest { val currentSessionCrossSigningInfo = givenCurrentSessionVerified(false) val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.UNVERIFIED, emptyList()) - filteredDeviceList.size shouldBeEqualTo 0 + filteredDeviceList.size shouldBeEqualTo 1 + filteredDeviceList shouldContain deviceWithoutEncryptionSupport } @Test From 5373771566311366b3f0a8eaaa770d5009b843d6 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 28 Dec 2022 09:55:22 +0100 Subject: [PATCH 156/246] Adding changelog entry --- changelog.d/7853.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7853.bugfix diff --git a/changelog.d/7853.bugfix b/changelog.d/7853.bugfix new file mode 100644 index 0000000000..885233553e --- /dev/null +++ b/changelog.d/7853.bugfix @@ -0,0 +1 @@ +[Session manager] Missing info when a session does not support encryption From e903dac22480525c97ba7ccc90cde41eeb811491 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 15:40:59 +0100 Subject: [PATCH 157/246] Adding changelog entry --- changelog.d/7864.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7864.wip diff --git a/changelog.d/7864.wip b/changelog.d/7864.wip new file mode 100644 index 0000000000..4dc55708be --- /dev/null +++ b/changelog.d/7864.wip @@ -0,0 +1 @@ +[Poll] Render active polls list of a room From cba960fbd782c91ab7de7e84c3635d3374ce3de2 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 16:05:52 +0100 Subject: [PATCH 158/246] Adding new entry "Poll history" into room profile screen --- library/ui-strings/src/main/res/values/strings.xml | 1 + .../app/features/roomprofile/RoomProfileController.kt | 7 +++++++ .../vector/app/features/roomprofile/RoomProfileFragment.kt | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 73cb60bb68..d7e56fcbb0 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2335,6 +2335,7 @@ "One person" "%1$d people" + Poll history Uploads Leave Room Leave diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index eb43a345f2..87f5657fc8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -56,6 +56,7 @@ class RoomProfileController @Inject constructor( fun onMemberListClicked() fun onBannedMemberListClicked() fun onNotificationsClicked() + fun onPollHistoryClicked() fun onUploadsClicked() fun createShortcut() fun onSettingsClicked() @@ -263,6 +264,12 @@ class RoomProfileController @Inject constructor( action = { callback?.onBannedMemberListClicked() } ) } + buildProfileAction( + id = "poll_history", + title = stringProvider.getString(R.string.room_profile_section_more_polls), + icon = R.drawable.ic_attachment_poll, + action = { callback?.onPollHistoryClicked() } + ) buildProfileAction( id = "uploads", title = stringProvider.getString(R.string.room_profile_section_more_uploads), diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index f4394111ab..a06fdf9152 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -269,6 +269,10 @@ class RoomProfileFragment : roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings) } + override fun onPollHistoryClicked() { + // TODO navigate to new screen + } + override fun onUploadsClicked() { roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomUploads) } From 7436c2e1f5a60ed8507c9df53b49bec014182e07 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 16:41:42 +0100 Subject: [PATCH 159/246] Navigate to new empty screen --- .../app/core/di/MavericksViewModelModule.kt | 6 ++ .../roomprofile/RoomProfileActivity.kt | 6 ++ .../roomprofile/RoomProfileFragment.kt | 2 +- .../roomprofile/RoomProfileSharedAction.kt | 1 + .../roomprofile/polls/RoomPollsAction.kt | 21 +++++++ .../roomprofile/polls/RoomPollsFragment.kt | 61 +++++++++++++++++++ .../roomprofile/polls/RoomPollsViewEvent.kt | 21 +++++++ .../roomprofile/polls/RoomPollsViewModel.kt | 41 +++++++++++++ .../roomprofile/polls/RoomPollsViewState.kt | 27 ++++++++ .../main/res/layout/fragment_room_polls.xml | 30 +++++++++ 10 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt create mode 100644 vector/src/main/res/layout/fragment_room_polls.xml 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 d22ab51e7a..911bbfa4a3 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 @@ -84,6 +84,7 @@ import im.vector.app.features.roomprofile.banned.RoomBannedMemberListViewModel import im.vector.app.features.roomprofile.members.RoomMemberListViewModel import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel import im.vector.app.features.roomprofile.permissions.RoomPermissionsViewModel +import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import im.vector.app.features.roomprofile.settings.RoomSettingsViewModel import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel @@ -697,4 +698,9 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(SetLinkViewModel::class) fun setLinkViewModelFactory(factory: SetLinkViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(RoomPollsViewModel::class) + fun roomPollsViewModelFactory(factory: RoomPollsViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index 526d676dee..3c37c92650 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -36,6 +36,7 @@ import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment +import im.vector.app.features.roomprofile.polls.RoomPollsFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.lib.core.utils.compat.getParcelableCompat @@ -98,6 +99,7 @@ class RoomProfileActivity : RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings() RoomProfileSharedAction.OpenRoomAliasesSettings -> openRoomAlias() RoomProfileSharedAction.OpenRoomPermissionsSettings -> openRoomPermissions() + RoomProfileSharedAction.OpenRoomPolls -> openRoomPolls() RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings() @@ -126,6 +128,10 @@ class RoomProfileActivity : finish() } + private fun openRoomPolls() { + addFragmentToBackstack(views.simpleFragmentContainer, RoomPollsFragment::class.java, roomProfileArgs) + } + private fun openRoomUploads() { addFragmentToBackstack(views.simpleFragmentContainer, RoomUploadsFragment::class.java, roomProfileArgs) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index a06fdf9152..51885dbf39 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -270,7 +270,7 @@ class RoomProfileFragment : } override fun onPollHistoryClicked() { - // TODO navigate to new screen + roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomPolls) } override fun onUploadsClicked() { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt index 7d62bb86a1..b243ceb206 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileSharedAction.kt @@ -25,6 +25,7 @@ sealed class RoomProfileSharedAction : VectorSharedAction { object OpenRoomSettings : RoomProfileSharedAction() object OpenRoomAliasesSettings : RoomProfileSharedAction() object OpenRoomPermissionsSettings : RoomProfileSharedAction() + object OpenRoomPolls : RoomProfileSharedAction() object OpenRoomUploads : RoomProfileSharedAction() object OpenRoomMembers : RoomProfileSharedAction() object OpenBannedRoomMembers : RoomProfileSharedAction() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt new file mode 100644 index 0000000000..895079ec90 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class RoomPollsAction : VectorViewModelAction diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt new file mode 100644 index 0000000000..a33dfdf93d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.args +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomPollsBinding +import im.vector.app.features.roomprofile.RoomProfileArgs + +@AndroidEntryPoint +class RoomPollsFragment : VectorBaseFragment() { + + private val roomProfileArgs: RoomProfileArgs by args() + + private val viewModel: RoomPollsViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsBinding { + return FragmentRoomPollsBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setupToolbar() + setupTabs() + } + + private fun setupToolbar() { + setupToolbar(views.roomPollsToolbar) + .allowBack() + } + + private fun setupTabs() { + // TODO + } + + override fun invalidate() = withState(viewModel) { + // TODO + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt new file mode 100644 index 0000000000..3896abf84c --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import im.vector.app.core.platform.VectorViewEvents + +sealed class RoomPollsViewEvent : VectorViewEvents diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt new file mode 100644 index 0000000000..cfda5af0cf --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +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.VectorViewModel + +class RoomPollsViewModel @AssistedInject constructor( + @Assisted initialState: RoomPollsViewState, +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomPollsViewState): RoomPollsViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + override fun handle(action: RoomPollsAction) { + // do nothing for now + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt new file mode 100644 index 0000000000..0233ddb693 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt @@ -0,0 +1,27 @@ +/* + * 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.roomprofile.polls + +import com.airbnb.mvrx.MavericksState +import im.vector.app.features.roomprofile.RoomProfileArgs + +data class RoomPollsViewState( + val roomId: String, +) : MavericksState { + + constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId) +} diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml new file mode 100644 index 0000000000..b1b91e9a18 --- /dev/null +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + From 10133bd20ffe12d059049d906079f3e74e57990f Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 29 Dec 2022 17:46:07 +0100 Subject: [PATCH 160/246] Setup tab layout when landing on the room polls screen --- .../src/main/res/values/strings.xml | 1 + .../roomprofile/polls/RoomPollsAction.kt | 2 +- .../roomprofile/polls/RoomPollsFragment.kt | 24 +++++++++---- .../polls/RoomPollsPagerAdapter.kt | 36 +++++++++++++++++++ .../roomprofile/polls/RoomPollsViewEvent.kt | 2 +- .../roomprofile/polls/RoomPollsViewModel.kt | 2 +- .../polls/active/RoomActivePollsFragment.kt | 35 ++++++++++++++++++ .../main/res/layout/fragment_room_polls.xml | 32 ++++++++++++++--- .../res/layout/fragment_room_polls_list.xml | 7 ++++ 9 files changed, 128 insertions(+), 13 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt create mode 100644 vector/src/main/res/layout/fragment_room_polls_list.xml diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index d7e56fcbb0..e0f2f7b288 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3191,6 +3191,7 @@ Voters see results as soon as they have voted Closed poll Results are only revealed when you end the poll + Active polls Share location diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 895079ec90..9d87f13f14 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index a33dfdf93d..7617da71df 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,9 @@ import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel -import com.airbnb.mvrx.withState +import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsBinding import im.vector.app.features.roomprofile.RoomProfileArgs @@ -35,6 +36,8 @@ class RoomPollsFragment : VectorBaseFragment() { private val viewModel: RoomPollsViewModel by fragmentViewModel() + private var tabLayoutMediator: TabLayoutMediator? = null + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsBinding { return FragmentRoomPollsBinding.inflate(inflater, container, false) } @@ -46,16 +49,25 @@ class RoomPollsFragment : VectorBaseFragment() { setupTabs() } + override fun onDestroyView() { + views.roomPollsViewPager.adapter = null + tabLayoutMediator?.detach() + tabLayoutMediator = null + super.onDestroyView() + } + private fun setupToolbar() { setupToolbar(views.roomPollsToolbar) .allowBack() } private fun setupTabs() { - // TODO - } + views.roomPollsViewPager.adapter = RoomPollsPagerAdapter(this) - override fun invalidate() = withState(viewModel) { - // TODO + tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> + when (position) { + 0 -> tab.text = getString(R.string.active_polls) + } + }.also { it.attach() } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt new file mode 100644 index 0000000000..5472782079 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt @@ -0,0 +1,36 @@ +/* + * 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.roomprofile.polls + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter +import im.vector.app.features.roomprofile.polls.active.RoomActivePollsFragment + +class RoomPollsPagerAdapter( + private val fragment: Fragment +) : FragmentStateAdapter(fragment) { + + override fun getItemCount() = 1 + + override fun createFragment(position: Int): Fragment { + return instantiateFragment(RoomActivePollsFragment::class.java.name) + } + + private fun instantiateFragment(fragmentName: String): Fragment { + return fragment.childFragmentManager.fragmentFactory.instantiate(fragment.requireContext().classLoader, fragmentName) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt index 3896abf84c..231123563a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewEvent.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index cfda5af0cf..42278ff976 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt new file mode 100644 index 0000000000..230da49b22 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -0,0 +1,35 @@ +/* + * 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.roomprofile.polls.active + +import android.view.LayoutInflater +import android.view.ViewGroup +import com.airbnb.mvrx.parentFragmentViewModel +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomPollsListBinding +import im.vector.app.features.roomprofile.polls.RoomPollsViewModel + +@AndroidEntryPoint +class RoomActivePollsFragment : VectorBaseFragment() { + + private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { + return FragmentRoomPollsListBinding.inflate(inflater, container, false) + } +} diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index b1b91e9a18..96a94cd9c5 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -1,7 +1,6 @@ @@ -21,10 +20,35 @@ + + + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/roomPollsTabs" /> diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml new file mode 100644 index 0000000000..1d672087a9 --- /dev/null +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -0,0 +1,7 @@ + + + + + From 9f97579f9dc4c928fd8f95449fde3a10b8f77040 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:07:50 +0100 Subject: [PATCH 161/246] Epoxy model for active poll --- .../polls/active/ActivePollItem.kt | 51 +++++++++++++++++++ .../src/main/res/layout/item_poll_active.xml | 42 +++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt create mode 100644 vector/src/main/res/layout/item_poll_active.xml diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt new file mode 100644 index 0000000000..2a927653f1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt @@ -0,0 +1,51 @@ +/* + * 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.roomprofile.polls.active + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.onClick + +@EpoxyModelClass +abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll_active) { + + @EpoxyAttribute + lateinit var formattedDate: String + + @EpoxyAttribute + lateinit var title: String + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var clickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.view.onClick(clickListener) + holder.date.text = formattedDate + holder.title.text = title + } + + class Holder : VectorEpoxyHolder() { + val date by bind(R.id.pollActiveDate) + val title by bind(R.id.pollActiveTitle) + } +} diff --git a/vector/src/main/res/layout/item_poll_active.xml b/vector/src/main/res/layout/item_poll_active.xml new file mode 100644 index 0000000000..8cf6c9e576 --- /dev/null +++ b/vector/src/main/res/layout/item_poll_active.xml @@ -0,0 +1,42 @@ + + + + + + + + + + From 7b63f891c33ffbb28d42491ac4ac48b89aef0a4e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:42:42 +0100 Subject: [PATCH 162/246] Epoxy controller to render active poll list --- .../features/roomprofile/polls/PollSummary.kt | 25 ++++++++++ .../roomprofile/polls/RoomPollsViewState.kt | 1 + .../polls/active/RoomActivePollsController.kt | 49 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt new file mode 100644 index 0000000000..3eb45c6144 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +sealed interface PollSummary { + data class ActivePoll( + val id: String, + val creationTimestamp: Long, + val title: String, + ) : PollSummary +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt index 0233ddb693..74794c99b1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewState.kt @@ -21,6 +21,7 @@ import im.vector.app.features.roomprofile.RoomProfileArgs data class RoomPollsViewState( val roomId: String, + val polls: List = emptyList(), ) : MavericksState { constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt new file mode 100644 index 0000000000..9f26569e58 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -0,0 +1,49 @@ +/* + * 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.roomprofile.polls.active + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.core.date.DateFormatKind +import im.vector.app.core.date.VectorDateFormatter +import im.vector.app.features.roomprofile.polls.PollSummary +import javax.inject.Inject + +class RoomActivePollsController @Inject constructor( + val dateFormatter: VectorDateFormatter, +) : TypedEpoxyController>() { + + interface Listener { + fun onPollClicked(pollId: String) + } + + var listener: Listener? = null + + override fun buildModels(data: List?) { + if (data == null) return + + val host = this + data.forEach { poll -> + activePollItem { + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) + title(poll.title) + clickListener { + host.listener?.onPollClicked(poll.id) + } + } + } + } +} From f20513eb16602a7b05d02231ca784215f0a28551 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 10:56:44 +0100 Subject: [PATCH 163/246] Render the active polls list on fragment --- .../polls/active/RoomActivePollsFragment.kt | 45 ++++++++++++++++++- .../res/layout/fragment_room_polls_list.xml | 13 ++++++ .../src/main/res/layout/item_poll_active.xml | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 230da49b22..10518d4b18 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -16,20 +16,63 @@ package im.vector.app.features.roomprofile.polls.active +import android.os.Bundle import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel +import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.cleanup import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding +import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsViewModel +import javax.inject.Inject @AndroidEntryPoint -class RoomActivePollsFragment : VectorBaseFragment() { +class RoomActivePollsFragment : + VectorBaseFragment(), + RoomActivePollsController.Listener { + + @Inject + lateinit var roomActivePollsController: RoomActivePollsController private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { return FragmentRoomPollsListBinding.inflate(inflater, container, false) } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupList() + } + + private fun setupList() { + roomActivePollsController.listener = this + views.activePollsList.adapter = roomActivePollsController.adapter + } + + override fun onDestroyView() { + cleanUpList() + super.onDestroyView() + } + + private fun cleanUpList() { + views.activePollsList.cleanup() + roomActivePollsController.listener = null + } + + override fun invalidate() = withState(viewModel) { viewState -> + renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) + } + + private fun renderList(polls: List) { + roomActivePollsController.setData(polls) + } + + override fun onPollClicked(pollId: String) { + // TODO navigate to details + } } diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 1d672087a9..39add6a298 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -1,7 +1,20 @@ + + diff --git a/vector/src/main/res/layout/item_poll_active.xml b/vector/src/main/res/layout/item_poll_active.xml index 8cf6c9e576..2db6450f94 100644 --- a/vector/src/main/res/layout/item_poll_active.xml +++ b/vector/src/main/res/layout/item_poll_active.xml @@ -10,6 +10,7 @@ android:id="@+id/pollActiveDate" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginTop="32dp" android:textAppearance="@style/TextAppearance.Vector.Caption" android:textColor="?vctr_content_tertiary" app:layout_constraintStart_toStartOf="parent" From 77d3b7da04b0e8e2cd9ff6ab44392565675eef11 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:40:41 +0100 Subject: [PATCH 164/246] Fix missing id in Epoxy model --- .../roomprofile/polls/active/RoomActivePollsController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index 9f26569e58..fd32ae51d0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -38,6 +38,7 @@ class RoomActivePollsController @Inject constructor( val host = this data.forEach { poll -> activePollItem { + id(poll.id) formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) title(poll.title) clickListener { From 8de86e74807339f5a02abcea6fd5c1452ffc68c9 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:59:48 +0100 Subject: [PATCH 165/246] Render mocked data get from use case --- .../roomprofile/polls/GetPollsUseCase.kt | 65 +++++++++++++++++++ .../roomprofile/polls/RoomPollsAction.kt | 4 +- .../roomprofile/polls/RoomPollsFilter.kt | 22 +++++++ .../roomprofile/polls/RoomPollsViewModel.kt | 23 ++++++- .../polls/active/RoomActivePollsFragment.kt | 10 ++- .../res/layout/fragment_room_polls_list.xml | 3 +- 6 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt new file mode 100644 index 0000000000..fa8c6d0aa6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class GetPollsUseCase @Inject constructor() { + + fun execute(filter: RoomPollsFilter): Flow> { + // TODO unmock and add unit tests + return when (filter) { + RoomPollsFilter.ACTIVE -> getActivePolls() + RoomPollsFilter.ENDED -> emptyFlow() + }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } + } + + private fun getActivePolls(): Flow> { + return flowOf( + listOf( + PollSummary.ActivePoll( + id = "id1", + // 2022/06/28 UTC+1 + creationTimestamp = 1656367200000, + title = "Which charity would you like to support?" + ), + PollSummary.ActivePoll( + id = "id2", + // 2022/06/26 UTC+1 + creationTimestamp = 1656194400000, + title = "Which sport should the pupils do this year?" + ), + PollSummary.ActivePoll( + id = "id3", + // 2022/06/24 UTC+1 + creationTimestamp = 1656021600000, + title = "What type of food should we have at the party?" + ), + PollSummary.ActivePoll( + id = "id4", + // 2022/06/22 UTC+1 + creationTimestamp = 1655848800000, + title = "What film should we show at the end of the year party?" + ), + ) + ) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 9d87f13f14..27753b6d16 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -18,4 +18,6 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction -sealed class RoomPollsAction : VectorViewModelAction +sealed interface RoomPollsAction : VectorViewModelAction { + data class SetFilter(val filter: RoomPollsFilter) : RoomPollsAction +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt new file mode 100644 index 0000000000..68ebb13f7d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt @@ -0,0 +1,22 @@ +/* + * 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.roomprofile.polls + +enum class RoomPollsFilter { + ACTIVE, + ENDED, +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 42278ff976..27ba6679d8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -23,9 +23,13 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class RoomPollsViewModel @AssistedInject constructor( @Assisted initialState: RoomPollsViewState, + private val getPollsUseCase: GetPollsUseCase, ) : VectorViewModel(initialState) { @AssistedFactory @@ -35,7 +39,24 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + private var pollsCollectionJob: Job? = null + + // TODO add unit tests override fun handle(action: RoomPollsAction) { - // do nothing for now + when (action) { + is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) + } + } + + override fun onCleared() { + pollsCollectionJob = null + super.onCleared() + } + + private fun handleSetFilter(filter: RoomPollsFilter) { + pollsCollectionJob?.cancel() + pollsCollectionJob = getPollsUseCase.execute(filter) + .onEach { setState { copy(polls = it) } } + .launchIn(viewModelScope) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 10518d4b18..ed851a045d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -24,9 +24,12 @@ import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary +import im.vector.app.features.roomprofile.polls.RoomPollsAction +import im.vector.app.features.roomprofile.polls.RoomPollsFilter import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import javax.inject.Inject @@ -51,7 +54,7 @@ class RoomActivePollsFragment : private fun setupList() { roomActivePollsController.listener = this - views.activePollsList.adapter = roomActivePollsController.adapter + views.activePollsList.configureWith(roomActivePollsController) } override fun onDestroyView() { @@ -64,6 +67,11 @@ class RoomActivePollsFragment : roomActivePollsController.listener = null } + override fun onResume() { + super.onResume() + viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilter.ACTIVE)) + } + override fun invalidate() = withState(viewModel) { viewState -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) } diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 39add6a298..1aa6625ae5 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -8,8 +8,9 @@ Date: Fri, 30 Dec 2022 12:08:55 +0100 Subject: [PATCH 166/246] Allow access of poll history only in debug variant --- .../roomprofile/RoomProfileController.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 87f5657fc8..30bd6c7ed3 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -18,6 +18,7 @@ package im.vector.app.features.roomprofile import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.epoxy.expandableTextItem import im.vector.app.core.epoxy.profiles.buildProfileAction @@ -264,12 +265,15 @@ class RoomProfileController @Inject constructor( action = { callback?.onBannedMemberListClicked() } ) } - buildProfileAction( - id = "poll_history", - title = stringProvider.getString(R.string.room_profile_section_more_polls), - icon = R.drawable.ic_attachment_poll, - action = { callback?.onPollHistoryClicked() } - ) + if (BuildConfig.DEBUG) { + // WIP, will be in release when related screens will be finished + buildProfileAction( + id = "poll_history", + title = stringProvider.getString(R.string.room_profile_section_more_polls), + icon = R.drawable.ic_attachment_poll, + action = { callback?.onPollHistoryClicked() } + ) + } buildProfileAction( id = "uploads", title = stringProvider.getString(R.string.room_profile_section_more_uploads), From 71b7edc6f2c095f476fda596cdc6cbaf2b3ca159 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 12:12:57 +0100 Subject: [PATCH 167/246] Adding debug log --- .../roomprofile/polls/active/RoomActivePollsFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index ed851a045d..b4e812a49e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -31,6 +31,7 @@ import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsAction import im.vector.app.features.roomprofile.polls.RoomPollsFilter import im.vector.app.features.roomprofile.polls.RoomPollsViewModel +import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint @@ -82,5 +83,6 @@ class RoomActivePollsFragment : override fun onPollClicked(pollId: String) { // TODO navigate to details + Timber.d("poll with id $pollId clicked") } } From bc985aa1ef310e5fe45cbaefc4b4cab71fa71dc8 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:19:50 +0100 Subject: [PATCH 168/246] Adding unit tests for ViewModel --- .../roomprofile/polls/RoomPollsViewModel.kt | 5 +- .../polls/RoomPollsViewModelTest.kt | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 27ba6679d8..7def7a508d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -16,6 +16,7 @@ package im.vector.app.features.roomprofile.polls +import androidx.annotation.VisibleForTesting import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -39,9 +40,9 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() - private var pollsCollectionJob: Job? = null + @VisibleForTesting + var pollsCollectionJob: Job? = null - // TODO add unit tests override fun handle(action: RoomPollsAction) { when (action) { is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) diff --git a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt new file mode 100644 index 0000000000..54b2a60d55 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt @@ -0,0 +1,76 @@ +/* + * 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.roomprofile.polls + +import com.airbnb.mvrx.test.MavericksTestRule +import im.vector.app.test.test +import im.vector.app.test.testDispatcher +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.flow.flowOf +import org.amshove.kluent.shouldNotBeNull +import org.junit.Rule +import org.junit.Test + +private const val ROOM_ID = "room-id" + +class RoomPollsViewModelTest { + + @get:Rule + val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher) + + private val fakeGetPollsUseCase = mockk() + private val initialState = RoomPollsViewState(ROOM_ID) + + private fun createViewModel(): RoomPollsViewModel { + return RoomPollsViewModel( + initialState = initialState, + getPollsUseCase = fakeGetPollsUseCase, + ) + } + + @Test + fun `given SetFilter action when handle then useCase is called with given filter and viewState is updated`() { + // Given + val filter = RoomPollsFilter.ACTIVE + val action = RoomPollsAction.SetFilter(filter = filter) + val polls = listOf(givenAPollSummary()) + every { fakeGetPollsUseCase.execute(any()) } returns flowOf(polls) + val viewModel = createViewModel() + val expectedViewState = initialState.copy(polls = polls) + + // When + val viewModelTest = viewModel.test() + viewModel.pollsCollectionJob = null + viewModel.handle(action) + + // Then + viewModelTest + .assertLatestState(expectedViewState) + .finish() + viewModel.pollsCollectionJob.shouldNotBeNull() + verify { + viewModel.pollsCollectionJob?.cancel() + fakeGetPollsUseCase.execute(filter) + } + } + + private fun givenAPollSummary(): PollSummary { + return mockk() + } +} From e0b77936c1e4325387a1e06e4d4fef34bd7acfdd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:27:11 +0100 Subject: [PATCH 169/246] Changing the date format --- .../roomprofile/polls/active/RoomActivePollsController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index fd32ae51d0..2fab886282 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -39,7 +39,7 @@ class RoomActivePollsController @Inject constructor( data.forEach { poll -> activePollItem { id(poll.id) - formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.EDIT_HISTORY_HEADER)) + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) title(poll.title) clickListener { host.listener?.onPollClicked(poll.id) From bd9c53a96c96aa870d3edcb8db44a52f6afb2d42 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:57:37 +0100 Subject: [PATCH 170/246] Show message when list is empty --- .../src/main/res/values/strings.xml | 3 ++- .../roomprofile/polls/RoomPollsFragment.kt | 2 +- .../polls/active/RoomActivePollsFragment.kt | 8 +++++-- .../res/layout/fragment_room_polls_list.xml | 23 ++++++++++++++++++- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index e0f2f7b288..43507e60ce 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3191,7 +3191,8 @@ Voters see results as soon as they have voted Closed poll Results are only revealed when you end the poll - Active polls + Active polls + There are no active polls in this room Share location diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index 7617da71df..5c150f4391 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -66,7 +66,7 @@ class RoomPollsFragment : VectorBaseFragment() { tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> when (position) { - 0 -> tab.text = getString(R.string.active_polls) + 0 -> tab.text = getString(R.string.room_polls_active) } }.also { it.attach() } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index b4e812a49e..4cc318edf9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -20,9 +20,11 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment @@ -55,7 +57,8 @@ class RoomActivePollsFragment : private fun setupList() { roomActivePollsController.listener = this - views.activePollsList.configureWith(roomActivePollsController) + views.roomPollsList.configureWith(roomActivePollsController) + views.roomPollsEmptyTitle.text = getString(R.string.room_polls_active_no_item) } override fun onDestroyView() { @@ -64,7 +67,7 @@ class RoomActivePollsFragment : } private fun cleanUpList() { - views.activePollsList.cleanup() + views.roomPollsList.cleanup() roomActivePollsController.listener = null } @@ -79,6 +82,7 @@ class RoomActivePollsFragment : private fun renderList(polls: List) { roomActivePollsController.setData(polls) + views.roomPollsEmptyTitle.isVisible = polls.isEmpty() } override fun onPollClicked(pollId: String) { diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 1aa6625ae5..6949bb0c67 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -6,7 +6,7 @@ android:layout_height="match_parent"> + + + From 6c0c5e506408d242ce1792ddd833c41836e573c3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 15:12:12 +0100 Subject: [PATCH 171/246] Rename poll item layout to be more generic --- .../app/features/roomprofile/polls/active/ActivePollItem.kt | 2 +- vector/src/main/res/layout/fragment_room_polls_list.xml | 2 +- .../src/main/res/layout/{item_poll_active.xml => item_poll.xml} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename vector/src/main/res/layout/{item_poll_active.xml => item_poll.xml} (100%) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt index 2a927653f1..35b1ecd6e1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt @@ -26,7 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick @EpoxyModelClass -abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll_active) { +abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll) { @EpoxyAttribute lateinit var formattedDate: String diff --git a/vector/src/main/res/layout/fragment_room_polls_list.xml b/vector/src/main/res/layout/fragment_room_polls_list.xml index 6949bb0c67..8eb27e5e00 100644 --- a/vector/src/main/res/layout/fragment_room_polls_list.xml +++ b/vector/src/main/res/layout/fragment_room_polls_list.xml @@ -15,7 +15,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:itemCount="5" - tools:listitem="@layout/item_poll_active" /> + tools:listitem="@layout/item_poll" /> Date: Fri, 30 Dec 2022 15:48:14 +0100 Subject: [PATCH 172/246] Replace usage of colorAccent --- vector/src/main/res/layout/fragment_room_polls.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index 96a94cd9c5..dcaf483251 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -24,22 +24,22 @@ android:id="@+id/roomPollsTabs" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="20dp" android:layout_marginHorizontal="10dp" + android:layout_marginTop="20dp" android:background="?android:colorBackground" app:layout_constraintBottom_toTopOf="@id/roomPollsViewPager" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/appBarLayout" + app:tabGravity="start" app:tabIndicatorFullWidth="false" app:tabIndicatorHeight="1dp" - app:tabPaddingBottom="-15dp" - app:tabTextColor="?vctr_content_primary" - app:tabSelectedTextColor="?colorAccent" - app:tabTextAppearance="@style/TextAppearance.Vector.Body" - app:tabGravity="start" app:tabMaxWidth="0dp" - app:tabMode="scrollable" /> + app:tabMode="scrollable" + app:tabPaddingBottom="-15dp" + app:tabSelectedTextColor="?colorSecondary" + app:tabTextAppearance="@style/TextAppearance.Vector.Body" + app:tabTextColor="?vctr_content_primary" /> Date: Fri, 30 Dec 2022 16:45:28 +0100 Subject: [PATCH 173/246] Ignore missing ContentDescription --- .../roomprofile/polls/active/RoomActivePollsController.kt | 4 +++- vector/src/main/res/layout/item_poll.xml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index 2fab886282..dc14ec366d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -33,7 +33,9 @@ class RoomActivePollsController @Inject constructor( var listener: Listener? = null override fun buildModels(data: List?) { - if (data == null) return + if (data.isNullOrEmpty()) { + return + } val host = this data.forEach { poll -> diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 2db6450f94..05e9b3a62a 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -25,7 +25,8 @@ android:src="@drawable/ic_attachment_poll" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/pollActiveDate" - app:tint="?vctr_content_secondary" /> + app:tint="?vctr_content_secondary" + tools:ignore="ContentDescription" /> Date: Wed, 4 Jan 2023 16:00:02 +0000 Subject: [PATCH 174/246] Translated using Weblate (Czech) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 0a7998deaa..0dfee753d7 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2860,7 +2860,7 @@ Přihlásit se pomocí QR kódu Naskenovat QR kód Možnost nahrávat a odesílat hlasové vysílání na časové ose místnosti. - Povolit hlasové vysílání (v aktivním vývoji) + Povolit hlasové vysílání Domovský server nepodporuje přihlášení pomocí QR kódu. Přihlášení bylo na druhém zařízení zrušeno. Tento QR kód je neplatný. From 08fbd55856629f403661756d2012d977540a3265 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:54:24 +0000 Subject: [PATCH 175/246] Translated using Weblate (Catalan) Currently translated at 98.2% (2531 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ca/ --- library/ui-strings/src/main/res/values-ca/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7e3e019ee5..b86a834a27 100644 --- a/library/ui-strings/src/main/res/values-ca/strings.xml +++ b/library/ui-strings/src/main/res/values-ca/strings.xml @@ -2790,7 +2790,7 @@ 2 1 Permet enregistrar i enviar emissions de veu dins una sala. - Activa l\'emissió de veu (en desenvolupament) + Activa l\'emissió de veu Activa la gravació d\'informació de client Desa el nom de client, la versió i l\'URL per reconèixer les sessions més fàcilment dins el gestor de sessions. Obté un millor control i visibilitat de totes les teves sessions. From fd7b35709e9bba40170fe598ed70a1bf8d1a8c04 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 4 Jan 2023 16:01:43 +0000 Subject: [PATCH 176/246] Translated using Weblate (Czech) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- library/ui-strings/src/main/res/values-cs/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 0dfee753d7..0a7998deaa 100644 --- a/library/ui-strings/src/main/res/values-cs/strings.xml +++ b/library/ui-strings/src/main/res/values-cs/strings.xml @@ -2860,7 +2860,7 @@ Přihlásit se pomocí QR kódu Naskenovat QR kód Možnost nahrávat a odesílat hlasové vysílání na časové ose místnosti. - Povolit hlasové vysílání + Povolit hlasové vysílání (v aktivním vývoji) Domovský server nepodporuje přihlášení pomocí QR kódu. Přihlášení bylo na druhém zařízení zrušeno. Tento QR kód je neplatný. From 805f514f8bce661e1046c20811e0586551ae20f1 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:48:53 +0000 Subject: [PATCH 177/246] Translated using Weblate (German) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- library/ui-strings/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5f1a47eba2..3f2ea694ca 100644 --- a/library/ui-strings/src/main/res/values-de/strings.xml +++ b/library/ui-strings/src/main/res/values-de/strings.xml @@ -2805,7 +2805,7 @@ Mit QR-Code anmelden QR-Code einlesen Zeichne Sprachnachrichten auf, während du sie in Echtzeit in den Raumverlauf sendest. - Sprachübertragung aktivieren (in aktiver Entwicklung) + Sprachübertragung aktivieren Der Heim-Server unterstützt Anmelden per QR-Code nicht. Die Anmeldung wurde vom anderen Gerät abgebrochen. Der QR-Code ist ungültig. From 5a6c5f16765ddbb963e3e101dcae00974cbe7e27 Mon Sep 17 00:00:00 2001 From: Alvaro V Date: Sun, 1 Jan 2023 12:29:39 +0000 Subject: [PATCH 178/246] Translated using Weblate (Spanish) Currently translated at 89.4% (2304 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/es/ --- .../src/main/res/values-es/strings.xml | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/library/ui-strings/src/main/res/values-es/strings.xml b/library/ui-strings/src/main/res/values-es/strings.xml index 3d10997233..e07c21d6a5 100644 --- a/library/ui-strings/src/main/res/values-es/strings.xml +++ b/library/ui-strings/src/main/res/values-es/strings.xml @@ -2632,8 +2632,8 @@ %1$s y %2$d otros %1$s y %2$s - Email no verificado, comprueba tu bandeja de entrada - Aquí es donde tus nuevas solicitudes y invitaciones estarán. + Correo electrónico no verificado, comprueba tu bandeja de entrada + Aquí es donde se encontrarán tus nuevas solicitudes e invitaciones. Nada nuevo. Invitaciones Los espacios son una nueva forma de agrupar salas y personas. Crea un espacio para empezar. @@ -2655,4 +2655,22 @@ %1$d seleccionado %1$d seleccionados + Habilitar compartición directa + Otorgar permiso + ${app_name} necesita permiso para mostrar notificaciones. +\nPor favor, otórgalo. + ${app_name} necesita permisos para mostrar notificaciones. Las notificaciones pueden mostrar tus mensajes, invitaciones, etc. +\n +\nPor favor, permite el acceso en las siguientes ventanas emergentes para poder visualizar notificaciones. + Prueba el editor de texto enriquecido (pronto llegará la opción de texto sin formato plain text) + Habilitar editor de texto enriquecido (rich text) + Crear MD únicamente al primer mensaje + Una versión simplificada de Element con pestañas opcionales + Habilitar nueva disposición + Sí, Parar + Deseleccionar todo + Ocultar los hijos de %s + Mostrar los hijos de %s + Has finalizado una transmisión de voz. + %1$s ha finalizado una transmisión de voz. \ No newline at end of file From c336f5aeee2f4efc219dac1ae91be9d9197b9a7d Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:55:35 +0000 Subject: [PATCH 179/246] Translated using Weblate (Estonian) Currently translated at 99.6% (2568 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- library/ui-strings/src/main/res/values-et/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 20592ff831..490145b5cc 100644 --- a/library/ui-strings/src/main/res/values-et/strings.xml +++ b/library/ui-strings/src/main/res/values-et/strings.xml @@ -2797,7 +2797,7 @@ \n \nJärgmistes vaadetes palun anna sellele rakendusele teavituste kuvamiseks vajalikud õigused. Võimalus salvestada ja postitada ringhäälingukõnesid jututoa ajajoonele. - Võta kasutusele ringhäälingukõned (aktiivses arenduses) + Võta kasutusele ringhäälingukõned Koduserver ei toeta muude seadmete võrku logimise võimalust. Sisselogimine katkestati teises seadmes. See QR-kood on vigane. From 4e59421fd9338bd105f822b89404b11605fb7125 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:58:09 +0000 Subject: [PATCH 180/246] Translated using Weblate (Persian) Currently translated at 100.0% (2576 of 2576 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e7d0640050..56dbe912c1 100644 --- a/library/ui-strings/src/main/res/values-fa/strings.xml +++ b/library/ui-strings/src/main/res/values-fa/strings.xml @@ -2737,7 +2737,7 @@ به تنظیمات -> امنیت و محرمانگی بروید کاره را روی افزارهٔ دیگرتان بگشایید پیوند دادن با این افزاره پشتیبانی نمی‌شود. - به کار انداختن پخش صدا (زیر توسعهٔ فعّال) + به کار انداختن پخش صدا نمایش کد QR روی این افزاره آغاز در صفحهٔ ورود گزینش‌«ورود با کد QR» From 19dd110963ac45a0e17e07bfb75c925a601c4a27 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:55:57 +0000 Subject: [PATCH 181/246] Translated using Weblate (French) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/ --- library/ui-strings/src/main/res/values-fr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 abe34dc579..33f1410502 100644 --- a/library/ui-strings/src/main/res/values-fr/strings.xml +++ b/library/ui-strings/src/main/res/values-fr/strings.xml @@ -2810,7 +2810,7 @@ 2 1 Pouvoir enregistrer et envoyer une diffusion audio dans l’historique du salon. - Activer la diffusion audio (en cours de développement) + Activer la diffusion audio Vous pouvez utiliser cet appareil pour connecter un appareil mobile ou un client web avec un QR code. Il y a deux façons de le faire : Se connecter avec un QR code Scanner le QR code From 9f43cbe67dc58aca5703aeeef8a37ab5a2ed69cc Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:56:16 +0000 Subject: [PATCH 182/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- library/ui-strings/src/main/res/values-hu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 b527a8fbab..1be136bb39 100644 --- a/library/ui-strings/src/main/res/values-hu/strings.xml +++ b/library/ui-strings/src/main/res/values-hu/strings.xml @@ -2813,7 +2813,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Biztonsági probléma lépett fel a biztonságos üzenetküldés beállításánál. Valamihez illetéktelenül fértek hozzá: Matrix szervered, Internet kapcsolatod, Eszközöd, A kérés sikertelen. Hang közvetítés felvételéhez és a szoba idővonalára küldéséhez. - Hang közvetítés engedélyezése (aktív fejlesztés alatt) + Hang közvetítés engedélyezése Pufferelés… Hang közvetítés szüneteltetése Hang közvetítés lejátszása vagy lejátszás folytatása From 90ae7e5ba2a6717214c64ff16c7a3f8fee098143 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:56:44 +0000 Subject: [PATCH 183/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/id/ --- library/ui-strings/src/main/res/values-in/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 835346979c..8715aa84e0 100644 --- a/library/ui-strings/src/main/res/values-in/strings.xml +++ b/library/ui-strings/src/main/res/values-in/strings.xml @@ -2761,7 +2761,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Homeserver tidak mendukung masuk dengan kode QR. Permintaan gagal. Memungkinkan untuk merekam dan mengirim siaran suara dalam lini masa ruangan. - Aktifkan siaran suara (dalam pengembangan aktif) + Aktifkan siaran suara Memuat… Jeda siaran suara Mainkan atau lanjutkan siaran suara From e57ff91030b5627de6fc7aae1047025c2f86ca90 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:56:59 +0000 Subject: [PATCH 184/246] Translated using Weblate (Italian) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- library/ui-strings/src/main/res/values-it/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 0b29e5f18f..46f7c3170c 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2797,7 +2797,7 @@ Accedi con codice QR Scansiona codice QR Registra e invia trasmissioni vocali nella linea temporale della stanza. - Attiva trasmissione vocale (in sviluppo attivo) + Attiva trasmissione vocale L\'homeserver non supporta l\'accesso con codice QR. L\'accesso è stato annullato sull\'altro dispositivo. Quel codice QR non è valido. From 93a3992451cd8696d034cbe73aa55d9e1e3a23c4 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 26 Dec 2022 11:46:54 +0000 Subject: [PATCH 185/246] Translated using Weblate (Italian) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- library/ui-strings/src/main/res/values-it/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 46f7c3170c..b1721449ad 100644 --- a/library/ui-strings/src/main/res/values-it/strings.xml +++ b/library/ui-strings/src/main/res/values-it/strings.xml @@ -2876,4 +2876,9 @@ Vuoi davvero fermare la tua trasmissione in diretta\? Verrà terminata la trasmissione e la registrazione completa sarà disponibile nella stanza. Fermare la trasmissione in diretta\? Sì, ferma + Modifica collegamento + Crea un collegamento + Collegamento + Testo + Imposta collegamento \ No newline at end of file From d0dddd1508f1e7df55a1dad6ab5e9194b12ddd89 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:57:18 +0000 Subject: [PATCH 186/246] Translated using Weblate (Dutch) Currently translated at 98.3% (2534 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/nl/ --- library/ui-strings/src/main/res/values-nl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 791b198193..5bc5305df4 100644 --- a/library/ui-strings/src/main/res/values-nl/strings.xml +++ b/library/ui-strings/src/main/res/values-nl/strings.xml @@ -2778,7 +2778,7 @@ 2 1 In staat zijn om spraakuitzendingen op te nemen en te verzenden in de tijdlijn van de kamer. - Spraakuitzending inschakelen (in actieve ontwikkeling) + Spraakuitzending inschakelen Noteer de naam, versie en url van de applicatie om sessies gemakkelijker te herkennen in sessiebeheer. Opname van applicatie informatie inschakelen Meer zichtbaarheid en controle over al je sessies. From d0dd78c5d0aa44324f98f8fc72e3ea87c228242b Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:58:28 +0000 Subject: [PATCH 187/246] Translated using Weblate (Polish) Currently translated at 92.8% (2391 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- library/ui-strings/src/main/res/values-pl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 97d5f70ae4..ae89c1aae3 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -2774,7 +2774,7 @@ Pokaż ostatnie rozmowy w systemowym menu udostępniania Bezpośrednie udostępnianie Bądź w stanie nagrywać i wysyłać transmisje głosowe na osi czasu pokoju. - Włącz transmicje głosowe (w trakcie aktywnego rozwoju) + Włącz transmicje głosowe Zachowuj nazwę aplikacji, wersję oraz jej url aby łatwiej rozpoznawać je w menedzerze sesji. Włącz rejestrowanie informacji o kliencie Miej lepszą kontrolę nad zalogowanymi sesjami. From aaa9e5a57fc987b214beced59112b5acf441699d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Romanik?= Date: Sat, 31 Dec 2022 02:18:28 +0000 Subject: [PATCH 188/246] Translated using Weblate (Polish) Currently translated at 92.8% (2391 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- library/ui-strings/src/main/res/values-pl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 ae89c1aae3..4b26562b06 100644 --- a/library/ui-strings/src/main/res/values-pl/strings.xml +++ b/library/ui-strings/src/main/res/values-pl/strings.xml @@ -39,7 +39,7 @@ %1$s wysłał(a) zaproszenie do %2$s aby dołączył(a) do tego pokoju %1$s zaakceptował(a) zaproszenie dla %2$s Urządzenie nadawcy nie wysłało nam kluczy do tej wiadomości. - %s zakutalizował(a) ten pokój. + %s zaktualizował(a) ten pokój. Wstępna synchronizacja: \nImportowanie konta… Wstępna synchronizacja: From 1b12fe80c1369f486461585251fcac1daee7310f Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:58:48 +0000 Subject: [PATCH 189/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- library/ui-strings/src/main/res/values-pt-rBR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1b6a342d4c..4a715103a6 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 @@ -2813,7 +2813,7 @@ Um problema de segurança foi encontrado ao configurar mensageria segura. Um dos seguintes pode ter sido comprometido: Seu servidorcasa; Sua(s) conexão(ões) de internet; Seu(s) dispositivo(s); A requisição falhou. Seja capaz de gravar e enviar broadcast de voz em timeline de sala. - Broadcast de voz (sob desenvolvimento ativo) + Broadcast de voz Buffering… Pausar broadcast de voz Tocar ou retomar broadcast de voz From fe2dd191327f529ea9f7982b1cb631aa12aad0de Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues Costa Date: Mon, 2 Jan 2023 19:01:38 +0000 Subject: [PATCH 190/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2576 of 2576 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 | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 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 4a715103a6..bc617c62f0 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 @@ -3,7 +3,7 @@ Convite de %s %1$s convidou %2$s %1$s convidou você - %1$s juntou-se à sala + %1$s entrou na sala %1$s saiu da sala %1$s rejeitou o convite %1$s removeu %2$s @@ -43,7 +43,7 @@ %1$s criou a sala Você criou a sala Você convidou %1$s - Você juntou-se à sala + Você entrou na sala Você saiu da sala Você rejeitou o convite Você removeu %1$s @@ -89,31 +89,31 @@ Você mudou o nível de poder de %1$s. %1$s mudou o nível de poder de %2$s. %1$s de %2$s para %3$s - Sinc inicial: + Sincronização inicial: \nImportando conta… - Sinc inicial: -\nImportando crypto - Sinc inicial: + Sincronização inicial: +\nImportando criptografia + Sincronização inicial: \nImportando salas - Sinc inicial: + Sincronização inicial: \nCarregando suas conversas -\nSe você tem se juntado a muitas salas, isto podia levar um tempo - Sinc inicial: -\nImportando salas convidadas - Sinc inicial: -\nImportando salas saídas - Sinc inicial: +\nSe você entrou em muitas salas, isso pode demorar + Sincronização inicial: +\nImportando salas para as quais foi convidado + Sincronização inicial: +\nImportando salas das quais saiu + Sincronização inicial: \nImportando dados de conta Enviando mensagem… - Convite de %1$s. Razão: %2$s - Seu convite. Razão: %1$s - %1$s convidou %2$s. Razão: %3$s - Você convidou %1$s. Razão: %2$s - %1$s convidou você. Razão: %2$s - %1$s juntou-se à sala. Razão: %2$s - Você juntou-se à sala. Razão: %1$s - %1$s saiu da sala. Razão: %2$s - Você saiu da sala. Razão: %1$s + Convite de %1$s. Motivo: %2$s + Seu convite. Motivo: %1$s + %1$s convidou %2$s. Motivo: %3$s + Você convidou %1$s. Motivo: %2$s + %1$s convidou você. Motivo: %2$s + %1$s entrou na sala. Motivo: %2$s + Você entrou na sala. Motivo: %1$s + %1$s saiu da sala. Motivo: %2$s + Você saiu da sala. Motivo: %1$s %1$s rejeitou o convite. Razão: %2$s Você rejeitou o convite. Razão: %1$s %1$s expulsou %2$s. Razão: %3$s @@ -160,10 +160,10 @@ %1$s tem prevenido visitantes de se juntarem à sala. Você tem permitido visitantes se juntarem aqui. %1$s tem permitido visitantes se juntarem aqui. - Você saiu. Razão: %1$s - %1$s saiu. Razão: %2$s - Você juntou-se. Razão: %1$s - %1$s juntou-se. Razão: %2$s + Você saiu. Motivo: %1$s + %1$s saiu. Motivo: %2$s + Você entrou. Motivo: %1$s + %1$s entrou. Motivo: %2$s Você revogou o convite para %1$s %1$s revogou o convite para %2$s Você convidou %1$s @@ -174,8 +174,8 @@ %1$s fez mensagens futuras visíveis para %2$s Você saiu da sala %1$s saiu da sala - Você juntou-se - %1$s juntou-se + Você entrou + %1$s entrou Você criou a discussão %1$s criou a discussão Sala vazia (era %s) @@ -1698,7 +1698,7 @@ Somente faça isto se você não tem nenhum outro dispositivo com o qual você pode verificar este dispositivo. Resettar tudo Esqueceu ou perdeu todas as opções de recuperação\? Resette tudo - Você juntou-se. + Você entrou. Mensagens neste chat são encriptadas ponta-a-ponta. Sair Configurações @@ -1722,7 +1722,7 @@ Resettar %1$s fez isto somente convite. Você fez isto somente convite. - %s juntou-se. + %s entrou. Filtrar usuárias(os) banidas(os) Testar Push @@ -1898,10 +1898,10 @@ Diretório de salas Novo valor Alterar - Sinc inicial: + Sincronização inicial: \nFazendo download de dados… - Sinc inicial: -\nEsperando por resposta de servidor… + Sincronização inicial: +\nEsperando pela resposta do servidor… Nível de confiança confiado Nível de confiança alerta Você tem certeza que você quer deletar todas as mensagens não-enviadas nesta sala\? @@ -2470,7 +2470,7 @@ \n%s \n \nNote que esta ação vai recomeçar o app e pode levar algum tempo. - Requisição de sinc inicial + Requisição de sincronização inicial Mostrar a info de perfil mais recente (avatar e nome de exibição) para todas as mensagens. Mostrar info de usuária(o) mais recente Ocupada(o) From 04df58ae308879a8ac57072cbcc1b1f1ca912380 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:59:11 +0000 Subject: [PATCH 191/246] Translated using Weblate (Russian) Currently translated at 99.5% (2564 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0fec10bebd..82f194baca 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -2794,7 +2794,7 @@ Рассмотрите возможность выхода из старых сеансов (%1$d дней или дольше), которые вы более не используете. Голосовая трансляция - Голосовые трансляции (в активной разработке) + Голосовые трансляции Записывает название клиента, версию и URL-адрес для более лёгкого распознавания сеансов в менеджере сеансов. Записывать информацию о клиенте Галерея From 668b70beaacefa29479ad755023079549352cef9 Mon Sep 17 00:00:00 2001 From: Nui Harime Date: Thu, 29 Dec 2022 10:08:35 +0000 Subject: [PATCH 192/246] Translated using Weblate (Russian) Currently translated at 99.5% (2564 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/ --- library/ui-strings/src/main/res/values-ru/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 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 82f194baca..0d8f1103fe 100644 --- a/library/ui-strings/src/main/res/values-ru/strings.xml +++ b/library/ui-strings/src/main/res/values-ru/strings.xml @@ -256,7 +256,7 @@ Переименовать Пожаловаться на содержимое или - Приглашение + Пригласить Выйти из учётной записи Голосовой вызов Видео вызов @@ -2714,7 +2714,7 @@ Новый вид Нечего отображать. Здесь будут отображаться непрочитанные сообщения, когда таковые будут. - Присущий системе + Как в системе Смена пространства Упрощённый Element с дополнительными вкладками Добро пожаловать в новый вид! From c26f8059fffcf74421b40a1c83d7f0634c86260c Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:59:24 +0000 Subject: [PATCH 193/246] Translated using Weblate (Slovak) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- library/ui-strings/src/main/res/values-sk/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 e3c78c9128..d46b4e8898 100644 --- a/library/ui-strings/src/main/res/values-sk/strings.xml +++ b/library/ui-strings/src/main/res/values-sk/strings.xml @@ -2867,7 +2867,7 @@ Pri nastavovaní zabezpečeného zasielania správ sa vyskytol bezpečnostný problém. Jedna z nasledujúcich možností môže byť kompromitovaná: Váš domovský server; Vaše internetové pripojenie (pripojenia); Vaše zariadenie (zariadenia); Žiadosť zlyhala. Možnosť nahrávania a odosielania hlasového vysielania v časovej osi miestnosti. - Zapnúť hlasové vysielanie (v štádiu aktívneho vývoja) + Zapnúť hlasové vysielanie Načítavanie do vyrovnávacej pamäte… Pozastaviť hlasové vysielanie Prehrať alebo pokračovať v nahrávaní hlasového vysielania From 38fd829425e9800eb4750d2e1ec2004c1ebe7010 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:47:51 +0000 Subject: [PATCH 194/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2558 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- library/ui-strings/src/main/res/values-sq/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index 3d08cf8115..ddd73ef5da 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2504,7 +2504,7 @@ %s \nduket paksa si i zbrazët. Jini në gjendje të incizoni dhe dërgoni transmetim zanor në rrjedhën kohore të dhomës. - Aktivizoni transmetim zanor (nën zhvillim aktiv) + Aktivizoni transmetim zanor Aktivizo regjistrim hollësish klienti Shihini më qartë dhe kontrolloni më mirë krejt sesionet tuaj. Aktivizo përgjegjës të ri sesionesh From 3670c49a6d1936953a87eccf053c87de04b5fa49 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Mon, 2 Jan 2023 16:03:33 +0000 Subject: [PATCH 195/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2558 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- library/ui-strings/src/main/res/values-sq/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index ddd73ef5da..3b233c087c 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2870,4 +2870,8 @@ Jeni i sigurt se doni të ndalet transmetimi juaj i drejtpërdrejtë\? Kjo do të përfundojë transmetimin dhe regjistrimi i plotë do të jetë i passhëm te dhoma. Të ndalet transmetimi i drejtpërdrejtë\? Po, Ndale + Përpunoni lidhje + Krijoni një lidhje + Lidhje + Tekst \ No newline at end of file From dd214909fdd18744c240ce4f2ec91070c79ba7b3 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:59:42 +0000 Subject: [PATCH 196/246] Translated using Weblate (Swedish) Currently translated at 99.6% (2567 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- library/ui-strings/src/main/res/values-sv/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sv/strings.xml b/library/ui-strings/src/main/res/values-sv/strings.xml index e8b903592c..373165802a 100644 --- a/library/ui-strings/src/main/res/values-sv/strings.xml +++ b/library/ui-strings/src/main/res/values-sv/strings.xml @@ -2728,7 +2728,7 @@ %s \nser lite tom ut. Möjliggör att spela in och skicka röstsändning i rummets tidslinje. - Aktivera röstsändning (under aktiv utveckling) + Aktivera röstsändning Spara klientnamnet, versionen, och URL:en för att enklare känna igen sessioner i sessionehanteraren. Aktivera klientinforapportering Ha bättre insyn i och kontroll över alla dina sessioner. From 724e4f4e735c6bbd4a8e4d350005123cd67ce8d8 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:53:19 +0000 Subject: [PATCH 197/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2576 of 2576 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 | 2 +- 1 file changed, 1 insertion(+), 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 6af8bc4ed6..ebe2dcaf4d 100644 --- a/library/ui-strings/src/main/res/values-uk/strings.xml +++ b/library/ui-strings/src/main/res/values-uk/strings.xml @@ -2921,7 +2921,7 @@ Під час налаштування захищеного обміну повідомленнями виникла проблема з безпекою. Можливо, порушено одне з таких налаштувань: Ваш домашній сервер; Ваше інтернет-з\'єднання; Ваш пристрій; Запит не виконаний. Можливість записувати та надсилати голосові трансляції до стрічки кімнати. - Увімкнути голосові трансляції (в активній розробці) + Увімкнути голосові трансляції Буферизація… Призупинити голосову трансляцію Відтворити або поновити відтворення голосової трансляції From 10701241b4e6d727f419f87303309caa786fd9c0 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:54:44 +0000 Subject: [PATCH 198/246] Translated using Weblate (Chinese (Simplified)) Currently translated at 99.5% (2565 of 2576 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 | 2 +- 1 file changed, 1 insertion(+), 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 03663405c7..9f975e61e4 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 @@ -2640,7 +2640,7 @@ %s \n看起来有点空荡荡的。 能够在房间时间线中录制和发送语音广播。 - 启用语音广播(正在积极开发中) + 启用语音广播 记录客户端名称、版本和网址,以便在会话管理器中更轻松地识别会话。 启用客户端信息记录 对所有会话有更好的可见性和控制。 From 7fff947f4fa60fed89ac2ad1094a0f8f17fbcca6 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 15:55:07 +0000 Subject: [PATCH 199/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- library/ui-strings/src/main/res/values-zh-rTW/strings.xml | 2 +- 1 file changed, 1 insertion(+), 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 6cb8c675da..e9fac15e27 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 @@ -2759,7 +2759,7 @@ 設定安全訊息傳遞時遇到安全問題。以下其中一項可能已被駭入:您的家伺服器、您的網際網路連線、您的裝置; 請求失敗。 可以在聊天室時間軸中錄製並傳送語音廣播。 - 啟用語音廣播(正在積極開發中) + 啟用語音廣播 正在緩衝…… 暫停語音廣播 播放或繼續語音廣播 From 565e63353df9c909206d54906b75de0ba2d2dbe2 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 26 Dec 2022 02:30:47 +0000 Subject: [PATCH 200/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2576 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- library/ui-strings/src/main/res/values-zh-rTW/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 e9fac15e27..934f5aa47b 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 @@ -2829,4 +2829,9 @@ 您真的想要停止您的即時廣播嗎?這將會結束廣播,完整的錄音會在聊天室中提供。 停止即時廣播? 是的,停止 + 編輯連結 + 建立連結 + 連結 + 文字 + 設定連結 \ No newline at end of file From 7e26c4b6f2533fde4db32d9fc986481f4e22bd4d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Jan 2023 09:48:25 +0100 Subject: [PATCH 201/246] Rename fun --- .../org/matrix/android/sdk/internal/crypto/DeviceListManager.kt | 2 +- .../matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt | 2 +- .../android/sdk/internal/crypto/store/db/RealmCryptoStore.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index 8ced0864d0..bb8acbf4b0 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -427,7 +427,7 @@ internal class DeviceListManager @Inject constructor( ) } - cryptoStore.storeUserDataToStore(userDataToStore) + cryptoStore.storeData(userDataToStore) // Update devices trust for these users // dispatchDeviceChange(downloadUsers) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index a74a7f2906..0c20ae79aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -601,5 +601,5 @@ internal interface IMXCryptoStore { /** * Store a bunch of data related to the users. @See [UserDataToStore]. */ - fun storeUserDataToStore(userDataToStore: UserDataToStore) + fun storeData(userDataToStore: UserDataToStore) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 06ae2c00b1..615df6a5b9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -1852,7 +1852,7 @@ internal class RealmCryptoStore @Inject constructor( } } - override fun storeUserDataToStore(userDataToStore: UserDataToStore) { + override fun storeData(userDataToStore: UserDataToStore) { doRealmTransaction("storeUserDataToStore", realmConfiguration) { realm -> userDataToStore.userDevices.forEach { storeUserDevices(realm, it.key, it.value) From 30940cb9370587b50fe2b5f05652032eaf0c1062 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Jan 2023 09:53:12 +0100 Subject: [PATCH 202/246] Rename `UserCrossSigningKeys` to `UserIdentity` --- ...ptoCrossSigningKeys.kt => UserIdentity.kt} | 2 +- .../sdk/internal/crypto/DeviceListManager.kt | 4 +- .../internal/crypto/store/IMXCryptoStore.kt | 9 +++-- .../internal/crypto/store/UserDataToStore.kt | 6 +-- .../crypto/store/db/RealmCryptoStore.kt | 40 +++++++++---------- 5 files changed, 32 insertions(+), 29 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/{CryptoCrossSigningKeys.kt => UserIdentity.kt} (96%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserIdentity.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserIdentity.kt index e0a422b54b..071db7f902 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKeys.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserIdentity.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning /** * Container for the three cross signing keys: master, self signing and user signing. */ -data class CryptoCrossSigningKeys( +data class UserIdentity( val masterKey: CryptoCrossSigningKey?, val selfSigningKey: CryptoCrossSigningKey?, val userSigningKey: CryptoCrossSigningKey?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index bb8acbf4b0..364d77f7ac 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -24,8 +24,8 @@ import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.extensions.measureMetric import org.matrix.android.sdk.api.metrics.DownloadDeviceKeysMetricsPlugin -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper @@ -420,7 +420,7 @@ internal class DeviceListManager @Inject constructor( val userSigningKey = response.userSigningKeys?.get(userId)?.toCryptoModel()?.also { Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}") } - userDataToStore.userCrossSigningKeys[userId] = CryptoCrossSigningKeys( + userDataToStore.userIdentities[userId] = UserIdentity( masterKey = masterKey, selfSigningKey = selfSigningKey, userSigningKey = userSigningKey diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 0c20ae79aa..10158c7a4d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -22,9 +22,9 @@ import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo import org.matrix.android.sdk.api.session.crypto.model.AuditTrail import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo @@ -245,9 +245,12 @@ internal interface IMXCryptoStore { */ fun storeUserDevices(userId: String, devices: Map?) - fun storeUserCrossSigningKeys( + /** + * Store the cross signing keys for the user userId. + */ + fun storeUserIdentity( userId: String, - cryptoCrossSigningKeys: CryptoCrossSigningKeys + userIdentity: UserIdentity ) /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt index 89cbe4e826..914ce4704e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/UserDataToStore.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.store -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo internal data class UserDataToStore( @@ -25,7 +25,7 @@ internal data class UserDataToStore( */ val userDevices: MutableMap> = mutableMapOf(), /** - * Map of userId -> [CryptoCrossSigningKeys]. + * Map of userId -> [UserIdentity]. */ - val userCrossSigningKeys: MutableMap = mutableMapOf(), + val userIdentities: MutableMap = mutableMapOf(), ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 615df6a5b9..1be88249eb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -33,9 +33,9 @@ import org.matrix.android.sdk.api.session.crypto.GlobalCryptoConfig import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.crypto.OutgoingKeyRequest import org.matrix.android.sdk.api.session.crypto.OutgoingRoomKeyRequestState -import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKeys import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserIdentity import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo import org.matrix.android.sdk.api.session.crypto.model.AuditTrail import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo @@ -330,23 +330,23 @@ internal class RealmCryptoStore @Inject constructor( } } - override fun storeUserCrossSigningKeys( + override fun storeUserIdentity( userId: String, - cryptoCrossSigningKeys: CryptoCrossSigningKeys, + userIdentity: UserIdentity, ) { - doRealmTransaction("storeUserCrossSigningKeys", realmConfiguration) { realm -> - storeUserCrossSigningKeys(realm, userId, cryptoCrossSigningKeys) + doRealmTransaction("storeUserIdentity", realmConfiguration) { realm -> + storeUserIdentity(realm, userId, userIdentity) } } - private fun storeUserCrossSigningKeys( + private fun storeUserIdentity( realm: Realm, userId: String, - keys: CryptoCrossSigningKeys, + userIdentity: UserIdentity, ) { UserEntity.getOrCreate(realm, userId) .let { userEntity -> - if (keys.masterKey == null || keys.selfSigningKey == null) { + if (userIdentity.masterKey == null || userIdentity.selfSigningKey == null) { // The user has disabled cross signing? userEntity.crossSigningInfoEntity?.deleteOnCascade() userEntity.crossSigningInfoEntity = null @@ -355,11 +355,11 @@ internal class RealmCryptoStore @Inject constructor( CrossSigningInfoEntity.getOrCreate(realm, userId).let { signingInfo -> // What should we do if we detect a change of the keys? val existingMaster = signingInfo.getMasterKey() - if (existingMaster != null && existingMaster.publicKeyBase64 == keys.masterKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingMaster, keys.masterKey) + if (existingMaster != null && existingMaster.publicKeyBase64 == userIdentity.masterKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingMaster, userIdentity.masterKey) } else { Timber.d("## CrossSigning MSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(keys.masterKey) + val keyEntity = crossSigningKeysMapper.map(userIdentity.masterKey) signingInfo.setMasterKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -374,11 +374,11 @@ internal class RealmCryptoStore @Inject constructor( } val existingSelfSigned = signingInfo.getSelfSignedKey() - if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == keys.selfSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingSelfSigned, keys.selfSigningKey) + if (existingSelfSigned != null && existingSelfSigned.publicKeyBase64 == userIdentity.selfSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingSelfSigned, userIdentity.selfSigningKey) } else { Timber.d("## CrossSigning SSK change for $userId") - val keyEntity = crossSigningKeysMapper.map(keys.selfSigningKey) + val keyEntity = crossSigningKeysMapper.map(userIdentity.selfSigningKey) signingInfo.setSelfSignedKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -390,13 +390,13 @@ internal class RealmCryptoStore @Inject constructor( } // Only for me - if (keys.userSigningKey != null) { + if (userIdentity.userSigningKey != null) { val existingUSK = signingInfo.getUserSigningKey() - if (existingUSK != null && existingUSK.publicKeyBase64 == keys.userSigningKey.unpaddedBase64PublicKey) { - crossSigningKeysMapper.update(existingUSK, keys.userSigningKey) + if (existingUSK != null && existingUSK.publicKeyBase64 == userIdentity.userSigningKey.unpaddedBase64PublicKey) { + crossSigningKeysMapper.update(existingUSK, userIdentity.userSigningKey) } else { Timber.d("## CrossSigning USK change for $userId") - val keyEntity = crossSigningKeysMapper.map(keys.userSigningKey) + val keyEntity = crossSigningKeysMapper.map(userIdentity.userSigningKey) signingInfo.setUserSignedKey(keyEntity) if (userId == this.userId) { shouldResetMyDevicesLocalTrust = true @@ -1857,8 +1857,8 @@ internal class RealmCryptoStore @Inject constructor( userDataToStore.userDevices.forEach { storeUserDevices(realm, it.key, it.value) } - userDataToStore.userCrossSigningKeys.forEach { - storeUserCrossSigningKeys(realm, it.key, it.value) + userDataToStore.userIdentities.forEach { + storeUserIdentity(realm, it.key, it.value) } } } From 682bb8bde09fb8f083a7442091b91a0214fe2cf9 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 14:06:58 +0100 Subject: [PATCH 203/246] VB - Stop listening if we reach the last received chunk and there is no last sequence number --- .../voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt index d56f4ad715..9cb894bb58 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt @@ -419,7 +419,9 @@ class VoiceBroadcastPlayerImpl @Inject constructor( // Next media player is already attached to this player and will start playing automatically if (nextMediaPlayer != null) return - val hasEnded = !isLiveListening && mostRecentVoiceBroadcastEvent?.content?.lastChunkSequence == playlist.currentSequence + val currentSequence = playlist.currentSequence ?: 0 + val lastChunkSequence = mostRecentVoiceBroadcastEvent?.content?.lastChunkSequence ?: 0 + val hasEnded = !isLiveListening && currentSequence >= lastChunkSequence if (hasEnded) { // We'll not receive new chunks anymore so we can stop the live listening stop() From 1a0f5bc9391281c4f8da36efbb1963d08896db18 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 4 Jan 2023 16:44:02 +0100 Subject: [PATCH 204/246] Edit voice broadcast string in labs --- 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 73cb60bb68..f10ec6731d 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3415,7 +3415,7 @@ Have greater visibility and control over all your sessions. Enable client info recording Record the client name, version, and url to recognise sessions more easily in session manager. - Enable voice broadcast (under active development) + Enable voice broadcast Be able to record and send voice broadcast in room timeline. From 27d32188bfd4af638af0a43b8044ce1a2a8701d7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Jan 2023 11:04:20 +0100 Subject: [PATCH 205/246] Aggregate data outside of the RealmCryptoStore. --- .../internal/crypto/DefaultCryptoService.kt | 33 ++++++++++++------- .../internal/crypto/store/IMXCryptoStore.kt | 28 +++++++--------- .../crypto/store/db/RealmCryptoStore.kt | 33 +++++++------------ .../room/create/CreateLocalRoomTask.kt | 2 +- .../session/sync/SyncResponseHandler.kt | 7 ++-- .../SyncResponsePostTreatmentAggregator.kt | 5 +++ .../session/sync/handler/CryptoSyncHandler.kt | 5 +-- .../sync/handler/room/RoomSyncHandler.kt | 4 +-- 8 files changed, 60 insertions(+), 57 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 128f06eacb..9f0a780703 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -89,6 +89,7 @@ import org.matrix.android.sdk.internal.crypto.model.SessionInfo import org.matrix.android.sdk.internal.crypto.model.toRest import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask @@ -192,21 +193,21 @@ internal class DefaultCryptoService @Inject constructor( private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) - fun onStateEvent(roomId: String, event: Event) { + fun onStateEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) { when (event.type) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) - EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) + EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event, cryptoStoreAggregator) } } - fun onLiveEvent(roomId: String, event: Event, isInitialSync: Boolean) { + fun onLiveEvent(roomId: String, event: Event, isInitialSync: Boolean, cryptoStoreAggregator: CryptoStoreAggregator?) { // handle state events if (event.isStateEvent()) { when (event.type) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) - EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) + EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event, cryptoStoreAggregator) } } @@ -384,7 +385,6 @@ internal class DefaultCryptoService @Inject constructor( } } } - cryptoStore.onSyncWillProcess() } private fun internalStart() { @@ -432,8 +432,8 @@ internal class DefaultCryptoService @Inject constructor( * * @param syncResponse the syncResponse */ - fun onSyncCompleted(syncResponse: SyncResponse) { - cryptoStore.onSyncCompleted() + fun onSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) { + cryptoStore.storeData(cryptoStoreAggregator) cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { if (syncResponse.deviceLists != null) { @@ -1000,15 +1000,26 @@ internal class DefaultCryptoService @Inject constructor( } } - private fun onRoomHistoryVisibilityEvent(roomId: String, event: Event) { + private fun onRoomHistoryVisibilityEvent(roomId: String, event: Event, cryptoStoreAggregator: CryptoStoreAggregator?) { if (!event.isStateEvent()) return val eventContent = event.content.toModel() val historyVisibility = eventContent?.historyVisibility if (historyVisibility == null) { - cryptoStore.setShouldShareHistory(roomId, false) + if (cryptoStoreAggregator != null) { + cryptoStoreAggregator.setShouldShareHistoryData[roomId] = false + } else { + // Store immediately + cryptoStore.setShouldShareHistory(roomId, false) + } } else { - cryptoStore.setShouldEncryptForInvitedMembers(roomId, historyVisibility != RoomHistoryVisibility.JOINED) - cryptoStore.setShouldShareHistory(roomId, historyVisibility.shouldShareHistory()) + if (cryptoStoreAggregator != null) { + cryptoStoreAggregator.setShouldEncryptForInvitedMembersData[roomId] = historyVisibility != RoomHistoryVisibility.JOINED + cryptoStoreAggregator.setShouldShareHistoryData[roomId] = historyVisibility.shouldShareHistory() + } else { + // Store immediately + cryptoStore.setShouldEncryptForInvitedMembers(roomId, historyVisibility != RoomHistoryVisibility.JOINED) + cryptoStore.setShouldShareHistory(roomId, historyVisibility.shouldShareHistory()) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 10158c7a4d..0305f73a7b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity import org.matrix.olm.OlmAccount import org.matrix.olm.OlmOutboundGroupSession @@ -48,21 +49,6 @@ import org.matrix.olm.OlmOutboundGroupSession */ internal interface IMXCryptoStore { - /** - * Notify the store that a sync response treatment is starting. - * Impacted methods: - * - [setShouldShareHistory] - * - [setShouldEncryptForInvitedMembers] - * @See [onSyncCompleted] to notify that the treatment is over. - */ - fun onSyncWillProcess() - - /** - * Notify the store that the sync treatment response is finished. - * The store will save all aggregated data. - */ - fun onSyncCompleted() - /** * @return the device id */ @@ -307,7 +293,11 @@ internal interface IMXCryptoStore { fun shouldEncryptForInvitedMembers(roomId: String): Boolean /** - * The data is not stored immediately, this MUST be call during a sync response treatment. + * Sets a boolean flag that will determine whether or not this device should encrypt Events for + * invited members. + * + * @param roomId the room id + * @param shouldEncryptForInvitedMembers The boolean flag */ fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) @@ -316,7 +306,6 @@ internal interface IMXCryptoStore { /** * Sets a boolean flag that will determine whether or not room history (existing inbound sessions) * will be shared to new user invites. - * The data is not stored immediately, this MUST be call during a sync response treatment. * * @param roomId the room id * @param shouldShareHistory The boolean flag @@ -601,6 +590,11 @@ internal interface IMXCryptoStore { fun tidyUpDataBase() fun getOutgoingRoomKeyRequests(inStates: Set): List + /** + * Store a bunch of data collected during a sync response treatment. @See [CryptoStoreAggregator]. + */ + fun storeData(cryptoStoreAggregator: CryptoStoreAggregator) + /** * Store a bunch of data related to the users. @See [UserDataToStore]. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 1be88249eb..b4368467a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -719,13 +719,17 @@ internal class RealmCryptoStore @Inject constructor( } override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) { - cryptoStoreAggregator?.setShouldEncryptForInvitedMembersData?.put(roomId, shouldEncryptForInvitedMembers) + doRealmTransaction("setShouldEncryptForInvitedMembers", realmConfiguration) { + CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers + } } override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) { Timber.tag(loggerTag.value) .v("setShouldShareHistory for room $roomId is $shouldShareHistory") - cryptoStoreAggregator?.setShouldShareHistoryData?.put(roomId, shouldShareHistory) + doRealmTransaction("setShouldShareHistory", realmConfiguration) { + CryptoRoomEntity.getOrCreate(it, roomId).shouldShareHistory = shouldShareHistory + } } override fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) { @@ -1823,37 +1827,24 @@ internal class RealmCryptoStore @Inject constructor( } } - private var cryptoStoreAggregator: CryptoStoreAggregator? = null - override fun onSyncWillProcess() { - if (cryptoStoreAggregator != null) { - Timber.e("cryptoStoreAggregator is not null...") - } - cryptoStoreAggregator = CryptoStoreAggregator() - } - - override fun onSyncCompleted() { - val aggregator = cryptoStoreAggregator ?: return Unit.also { - Timber.e("cryptoStoreAggregator is null...") - } - cryptoStoreAggregator = null - - if (aggregator.isEmpty()) { + override fun storeData(cryptoStoreAggregator: CryptoStoreAggregator) { + if (cryptoStoreAggregator.isEmpty()) { return } - doRealmTransaction("onSyncCompleted", realmConfiguration) { realm -> + doRealmTransaction("storeData - CryptoStoreAggregator", realmConfiguration) { realm -> // setShouldShareHistory - aggregator.setShouldShareHistoryData.forEach { + cryptoStoreAggregator.setShouldShareHistoryData.forEach { CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value } // setShouldEncryptForInvitedMembers - aggregator.setShouldEncryptForInvitedMembersData.forEach { + cryptoStoreAggregator.setShouldEncryptForInvitedMembersData.forEach { CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value } } } override fun storeData(userDataToStore: UserDataToStore) { - doRealmTransaction("storeUserDataToStore", realmConfiguration) { realm -> + doRealmTransaction("storeData - UserDataToStore", realmConfiguration) { realm -> userDataToStore.userDevices.forEach { storeUserDevices(realm, it.key, it.value) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateLocalRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateLocalRoomTask.kt index 793c2573be..653069b3c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateLocalRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateLocalRoomTask.kt @@ -176,7 +176,7 @@ internal class DefaultCreateLocalRoomTask @Inject constructor( } // Give info to crypto module - cryptoService.onStateEvent(roomId, event) + cryptoService.onStateEvent(roomId, event, null) } roomMemberContentsByUser.getOrPut(event.senderId) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 05d50d9595..cb407bb1cb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.DefaultCryptoService +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.session.SessionListeners @@ -92,7 +93,7 @@ internal class SyncResponseHandler @Inject constructor( postTreatmentSyncResponse(syncResponse, isInitialSync) - markCryptoSyncCompleted(syncResponse) + markCryptoSyncCompleted(syncResponse, aggregator.cryptoStoreAggregator) handlePostSync() @@ -218,10 +219,10 @@ internal class SyncResponseHandler @Inject constructor( } } - private fun markCryptoSyncCompleted(syncResponse: SyncResponse) { + private fun markCryptoSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) { relevantPlugins.measureSpan("task", "crypto_sync_handler_onSyncCompleted") { measureTimeMillis { - cryptoSyncHandler.onSyncCompleted(syncResponse) + cryptoSyncHandler.onSyncCompleted(syncResponse, cryptoStoreAggregator) }.also { Timber.v("cryptoSyncHandler.onSyncCompleted took $it ms") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt index 2b7f936fa8..af05e08da3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.session.sync +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator + internal class SyncResponsePostTreatmentAggregator { // List of RoomId val ephemeralFilesToDelete = mutableListOf() @@ -28,4 +30,7 @@ internal class SyncResponsePostTreatmentAggregator { // Set of users to call `crossSigningService.checkTrustAndAffectedRoomShields` once per sync val userIdsForCheckingTrustAndAffectedRoomShields = mutableSetOf() + + // For the crypto store + val cryptoStoreAggregator = CryptoStoreAggregator() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt index 551db52dbd..7224b0c29c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService +import org.matrix.android.sdk.internal.crypto.store.db.CryptoStoreAggregator import org.matrix.android.sdk.internal.crypto.tasks.toDeviceTracingId import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.session.sync.ProgressReporter @@ -85,8 +86,8 @@ internal class CryptoSyncHandler @Inject constructor( } } - fun onSyncCompleted(syncResponse: SyncResponse) { - cryptoService.onSyncCompleted(syncResponse) + fun onSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) { + cryptoService.onSyncCompleted(syncResponse, cryptoStoreAggregator) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index ccc3820bb6..5e4886ce1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -258,7 +258,7 @@ internal class RoomSyncHandler @Inject constructor( root = eventEntity } // Give info to crypto module - cryptoService.onStateEvent(roomId, event) + cryptoService.onStateEvent(roomId, event, aggregator.cryptoStoreAggregator) roomMemberEventHandler.handle(realm, roomId, event, isInitialSync, aggregator) } } @@ -495,7 +495,7 @@ internal class RoomSyncHandler @Inject constructor( } } // Give info to crypto module - cryptoService.onLiveEvent(roomEntity.roomId, event, isInitialSync) + cryptoService.onLiveEvent(roomEntity.roomId, event, isInitialSync, aggregator.cryptoStoreAggregator) // Try to remove local echo event.unsignedData?.transactionId?.also { txId -> From dbf3b763311ea0faae4df39a178ec584f5537f95 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 5 Jan 2023 11:54:19 +0100 Subject: [PATCH 206/246] Update doc. --- .../matrix/android/sdk/internal/crypto/DefaultCryptoService.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 9f0a780703..50497e3a27 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -431,6 +431,7 @@ internal class DefaultCryptoService @Inject constructor( * A sync response has been received. * * @param syncResponse the syncResponse + * @param cryptoStoreAggregator data aggregated during the sync response treatment to store */ fun onSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) { cryptoStore.storeData(cryptoStoreAggregator) From 0d2fb8e3d089bce9c47f3ace8b170be6c661ffe5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Jan 2023 10:17:35 +0100 Subject: [PATCH 207/246] Lint: fix KotlinNullnessAnnotation warning --- .../java/org/matrix/android/sdk/internal/di/SerializeNulls.kt | 2 -- .../internal/network/interceptors/FormattedJsonHttpLogger.kt | 3 +-- .../android/sdk/internal/network/parsing/CheckNumberType.kt | 3 --- tools/lint/lint.xml | 1 + .../java/im/vector/app/core/resources/StringArrayProvider.kt | 2 -- .../main/java/im/vector/app/core/resources/StringProvider.kt | 4 ---- 6 files changed, 2 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt index 9bd197e42e..f89221b627 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.di -import androidx.annotation.Nullable import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonQualifier import com.squareup.moshi.Moshi @@ -28,7 +27,6 @@ import java.lang.reflect.Type internal annotation class SerializeNulls { companion object { val JSON_ADAPTER_FACTORY: JsonAdapter.Factory = object : JsonAdapter.Factory { - @Nullable override fun create(type: Type, annotations: Set, moshi: Moshi): JsonAdapter<*>? { val nextAnnotations = Types.nextAnnotations(annotations, SerializeNulls::class.java) ?: return null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt index 4e0525536c..334a8c5076 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.network.interceptors -import androidx.annotation.NonNull import okhttp3.logging.HttpLoggingInterceptor import org.json.JSONArray import org.json.JSONException @@ -38,7 +37,7 @@ internal class FormattedJsonHttpLogger( * @param message */ @Synchronized - override fun log(@NonNull message: String) { + override fun log(message: String) { Timber.v(message) // Try to log formatted Json only if there is a chance that [message] contains Json. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt index 8b54978279..6c28b9fcce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.network.parsing -import androidx.annotation.Nullable import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter @@ -32,14 +31,12 @@ internal interface CheckNumberType { companion object { val JSON_ADAPTER_FACTORY = object : JsonAdapter.Factory { - @Nullable override fun create(type: Type, annotations: Set, moshi: Moshi): JsonAdapter<*>? { if (type !== Any::class.java) { return null } val delegate: JsonAdapter = moshi.nextAdapter(this, Any::class.java, emptySet()) return object : JsonAdapter() { - @Nullable @Throws(IOException::class) override fun fromJson(reader: JsonReader): Any? { return if (reader.peek() !== JsonReader.Token.NUMBER) { diff --git a/tools/lint/lint.xml b/tools/lint/lint.xml index 3d3b073749..dbe30f2267 100644 --- a/tools/lint/lint.xml +++ b/tools/lint/lint.xml @@ -77,6 +77,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/resources/StringArrayProvider.kt b/vector/src/main/java/im/vector/app/core/resources/StringArrayProvider.kt index 9ed3c02ba4..3c057e0635 100644 --- a/vector/src/main/java/im/vector/app/core/resources/StringArrayProvider.kt +++ b/vector/src/main/java/im/vector/app/core/resources/StringArrayProvider.kt @@ -18,7 +18,6 @@ package im.vector.app.core.resources import android.content.res.Resources import androidx.annotation.ArrayRes -import androidx.annotation.NonNull import javax.inject.Inject class StringArrayProvider @Inject constructor(private val resources: Resources) { @@ -31,7 +30,6 @@ class StringArrayProvider @Inject constructor(private val resources: Resources) * @return The string array associated with the resource, stripped of styled * text information. */ - @NonNull fun getStringArray(@ArrayRes resId: Int): Array { return resources.getStringArray(resId) } diff --git a/vector/src/main/java/im/vector/app/core/resources/StringProvider.kt b/vector/src/main/java/im/vector/app/core/resources/StringProvider.kt index 7e322daaae..e5f48f8be0 100644 --- a/vector/src/main/java/im/vector/app/core/resources/StringProvider.kt +++ b/vector/src/main/java/im/vector/app/core/resources/StringProvider.kt @@ -17,7 +17,6 @@ package im.vector.app.core.resources import android.content.res.Resources -import androidx.annotation.NonNull import androidx.annotation.PluralsRes import androidx.annotation.StringRes import javax.inject.Inject @@ -32,7 +31,6 @@ class StringProvider @Inject constructor(private val resources: Resources) { * @return The string data associated with the resource, stripped of styled * text information. */ - @NonNull fun getString(@StringRes resId: Int): String { return resources.getString(resId) } @@ -48,12 +46,10 @@ class StringProvider @Inject constructor(private val resources: Resources) { * @return The string data associated with the resource, formatted and * stripped of styled text information. */ - @NonNull fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String { return resources.getString(resId, *formatArgs) } - @NonNull fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any?): String { return resources.getQuantityString(resId, quantity, *formatArgs) } From bbb0036647a542d2f0df844c29dbf553c5625f98 Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Thu, 5 Jan 2023 13:07:19 +0000 Subject: [PATCH 208/246] [Rich text editor] Add list formatting buttons to the rich text editor (#7887) --- changelog.d/7887.feature | 1 + dependencies.gradle | 2 +- .../src/main/res/values/strings.xml | 2 ++ .../detail/composer/RichTextComposerLayout.kt | 6 +++++ .../res/drawable/ic_composer_bullet_list.xml | 13 ++++++++++ .../drawable/ic_composer_numbered_list.xml | 24 +++++++++++++++++++ .../res/layout/composer_rich_text_layout.xml | 2 ++ 7 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 changelog.d/7887.feature create mode 100644 vector/src/main/res/drawable/ic_composer_bullet_list.xml create mode 100644 vector/src/main/res/drawable/ic_composer_numbered_list.xml diff --git a/changelog.d/7887.feature b/changelog.d/7887.feature new file mode 100644 index 0000000000..1f1c29761a --- /dev/null +++ b/changelog.d/7887.feature @@ -0,0 +1 @@ +"[Rich text editor] Add list formatting buttons to the rich text editor" \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index d8a97ba0b1..76ff9b0c6f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -101,7 +101,7 @@ ext.libs = [ ], element : [ 'opusencoder' : "io.element.android:opusencoder:1.1.0", - 'wysiwyg' : "io.element.android:wysiwyg:0.10.0" + 'wysiwyg' : "io.element.android:wysiwyg:0.13.0" ], squareup : [ 'moshi' : "com.squareup.moshi:moshi:$moshi", diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 73cb60bb68..ec707bd39a 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3485,6 +3485,8 @@ Apply strikethrough format Apply underline format Set link + Toggle numbered list + Toggle bullet list Toggle full screen mode Text diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt index 543210e006..1bb82b41fe 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/RichTextComposerLayout.kt @@ -240,6 +240,12 @@ internal class RichTextComposerLayout @JvmOverloads constructor( } } } + addRichTextMenuItem(R.drawable.ic_composer_bullet_list, R.string.rich_text_editor_bullet_list, ComposerAction.UNORDERED_LIST) { + views.richTextComposerEditText.toggleList(ordered = false) + } + addRichTextMenuItem(R.drawable.ic_composer_numbered_list, R.string.rich_text_editor_numbered_list, ComposerAction.ORDERED_LIST) { + views.richTextComposerEditText.toggleList(ordered = true) + } } fun setLink(link: String?) = diff --git a/vector/src/main/res/drawable/ic_composer_bullet_list.xml b/vector/src/main/res/drawable/ic_composer_bullet_list.xml new file mode 100644 index 0000000000..f6febc88f0 --- /dev/null +++ b/vector/src/main/res/drawable/ic_composer_bullet_list.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/vector/src/main/res/drawable/ic_composer_numbered_list.xml b/vector/src/main/res/drawable/ic_composer_numbered_list.xml new file mode 100644 index 0000000000..d6a860c4c8 --- /dev/null +++ b/vector/src/main/res/drawable/ic_composer_numbered_list.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/vector/src/main/res/layout/composer_rich_text_layout.xml b/vector/src/main/res/layout/composer_rich_text_layout.xml index 3484616c72..7cc2d48cda 100644 --- a/vector/src/main/res/layout/composer_rich_text_layout.xml +++ b/vector/src/main/res/layout/composer_rich_text_layout.xml @@ -180,6 +180,8 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:minHeight="52dp" + android:requiresFadingEdge="horizontal" + android:fadingEdgeLength="28dp" app:layout_constraintTop_toBottomOf="@id/composerEditTextOuterBorder" app:layout_constraintStart_toEndOf="@id/attachmentButton" app:layout_constraintEnd_toStartOf="@id/sendButton" From 87e661e3b5d895990648f5cc0e71e60d08d10982 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 5 Jan 2023 14:36:22 +0100 Subject: [PATCH 209/246] Add changelog file --- changelog.d/7899.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7899.bugfix diff --git a/changelog.d/7899.bugfix b/changelog.d/7899.bugfix new file mode 100644 index 0000000000..d95af29d8d --- /dev/null +++ b/changelog.d/7899.bugfix @@ -0,0 +1 @@ +[Voice Broadcast] Stop listening if we reach the last received chunk and there is no last sequence number From d60403545c4f323f7067bef06776660cdcf4b4d3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:09:41 +0100 Subject: [PATCH 210/246] Renaming of filter enum --- .../app/features/roomprofile/polls/GetPollsUseCase.kt | 6 +++--- .../app/features/roomprofile/polls/RoomPollsAction.kt | 2 +- .../polls/{RoomPollsFilter.kt => RoomPollsFilterType.kt} | 2 +- .../app/features/roomprofile/polls/RoomPollsViewModel.kt | 2 +- .../roomprofile/polls/active/RoomActivePollsFragment.kt | 4 ++-- .../features/roomprofile/polls/RoomPollsViewModelTest.kt | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename vector/src/main/java/im/vector/app/features/roomprofile/polls/{RoomPollsFilter.kt => RoomPollsFilterType.kt} (95%) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt index fa8c6d0aa6..d35d192e04 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -24,11 +24,11 @@ import javax.inject.Inject class GetPollsUseCase @Inject constructor() { - fun execute(filter: RoomPollsFilter): Flow> { + fun execute(filter: RoomPollsFilterType): Flow> { // TODO unmock and add unit tests return when (filter) { - RoomPollsFilter.ACTIVE -> getActivePolls() - RoomPollsFilter.ENDED -> emptyFlow() + RoomPollsFilterType.ACTIVE -> getActivePolls() + RoomPollsFilterType.ENDED -> emptyFlow() }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 27753b6d16..5f074bdd6f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -19,5 +19,5 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction sealed interface RoomPollsAction : VectorViewModelAction { - data class SetFilter(val filter: RoomPollsFilter) : RoomPollsAction + data class SetFilter(val filter: RoomPollsFilterType) : RoomPollsAction } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt similarity index 95% rename from vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt rename to vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt index 68ebb13f7d..39f1163536 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilter.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt @@ -16,7 +16,7 @@ package im.vector.app.features.roomprofile.polls -enum class RoomPollsFilter { +enum class RoomPollsFilterType { ACTIVE, ENDED, } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 7def7a508d..7bc06894fa 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -54,7 +54,7 @@ class RoomPollsViewModel @AssistedInject constructor( super.onCleared() } - private fun handleSetFilter(filter: RoomPollsFilter) { + private fun handleSetFilter(filter: RoomPollsFilterType) { pollsCollectionJob?.cancel() pollsCollectionJob = getPollsUseCase.execute(filter) .onEach { setState { copy(polls = it) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 4cc318edf9..61c7e961bd 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -31,7 +31,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary import im.vector.app.features.roomprofile.polls.RoomPollsAction -import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.RoomPollsFilterType import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import timber.log.Timber import javax.inject.Inject @@ -73,7 +73,7 @@ class RoomActivePollsFragment : override fun onResume() { super.onResume() - viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilter.ACTIVE)) + viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilterType.ACTIVE)) } override fun invalidate() = withState(viewModel) { viewState -> diff --git a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt index 54b2a60d55..0dce2dd6e0 100644 --- a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt @@ -47,7 +47,7 @@ class RoomPollsViewModelTest { @Test fun `given SetFilter action when handle then useCase is called with given filter and viewState is updated`() { // Given - val filter = RoomPollsFilter.ACTIVE + val filter = RoomPollsFilterType.ACTIVE val action = RoomPollsAction.SetFilter(filter = filter) val polls = listOf(givenAPollSummary()) every { fakeGetPollsUseCase.execute(any()) } returns flowOf(polls) From ff9e78be42c500fd3a0985cadb9db67be8c54df3 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:20:20 +0100 Subject: [PATCH 211/246] Use classical for loop instead of forEach --- .../roomprofile/polls/active/RoomActivePollsController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt index dc14ec366d..7a7c818693 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt @@ -38,7 +38,7 @@ class RoomActivePollsController @Inject constructor( } val host = this - data.forEach { poll -> + for (poll in data) { activePollItem { id(poll.id) formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) From 2dab6ed052912e6296b643d15b30c69ce0df7516 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:27:11 +0100 Subject: [PATCH 212/246] Fix horizontal margin of tabs --- vector/src/main/res/layout/fragment_room_polls.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/fragment_room_polls.xml b/vector/src/main/res/layout/fragment_room_polls.xml index dcaf483251..396d6fd8c5 100644 --- a/vector/src/main/res/layout/fragment_room_polls.xml +++ b/vector/src/main/res/layout/fragment_room_polls.xml @@ -24,7 +24,7 @@ android:id="@+id/roomPollsTabs" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginHorizontal="10dp" + android:layout_marginHorizontal="4dp" android:layout_marginTop="20dp" android:background="?android:colorBackground" app:layout_constraintBottom_toTopOf="@id/roomPollsViewPager" From 7fc9705f3a92d392b0ce8855ecd79e6abb32cc40 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 16:37:06 +0100 Subject: [PATCH 213/246] Adding importantForAccessibility attribute to icon --- vector/src/main/res/layout/item_poll.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 05e9b3a62a..956ecf9b3c 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -22,6 +22,7 @@ android:layout_width="16dp" android:layout_height="16dp" android:layout_marginTop="12dp" + android:importantForAccessibility="no" android:src="@drawable/ic_attachment_poll" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/pollActiveDate" From 0b535910d649d5c9dbe3777f15971aabb4cc973c Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 15:50:32 +0100 Subject: [PATCH 214/246] Adding changelog entry --- changelog.d/7864.wip | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.d/7864.wip b/changelog.d/7864.wip index 4dc55708be..e1187ee1e7 100644 --- a/changelog.d/7864.wip +++ b/changelog.d/7864.wip @@ -1 +1,2 @@ [Poll] Render active polls list of a room +[Poll] Render past polls list of a room From cb45056c1a311ec652d72a198c089abb66f78669 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 17:28:57 +0100 Subject: [PATCH 215/246] Mutualizing list fragments and add ended polls tab --- .../src/main/res/values/strings.xml | 2 + .../roomprofile/polls/GetPollsUseCase.kt | 9 +- .../features/roomprofile/polls/PollSummary.kt | 6 ++ .../roomprofile/polls/RoomPollsAction.kt | 4 +- .../roomprofile/polls/RoomPollsFragment.kt | 1 + .../polls/RoomPollsPagerAdapter.kt | 8 +- .../roomprofile/polls/RoomPollsViewModel.kt | 25 ++---- .../polls/active/RoomActivePollsFragment.kt | 70 ++------------- .../polls/ended/RoomEndedPollsFragment.kt | 34 +++++++ .../RoomPollItem.kt} | 4 +- .../RoomPollsController.kt} | 43 ++++++--- .../polls/list/RoomPollsListFragment.kt | 90 +++++++++++++++++++ 12 files changed, 190 insertions(+), 106 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt rename vector/src/main/java/im/vector/app/features/roomprofile/polls/{active/ActivePollItem.kt => list/RoomPollItem.kt} (90%) rename vector/src/main/java/im/vector/app/features/roomprofile/polls/{active/RoomActivePollsController.kt => list/RoomPollsController.kt} (50%) create mode 100644 vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 43507e60ce..6120398566 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3193,6 +3193,8 @@ Results are only revealed when you end the poll Active polls There are no active polls in this room + Past polls + There are no past polls in this room Share location diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt index d35d192e04..06915c7b6a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -17,19 +17,16 @@ package im.vector.app.features.roomprofile.polls import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import javax.inject.Inject class GetPollsUseCase @Inject constructor() { - fun execute(filter: RoomPollsFilterType): Flow> { + fun execute(): Flow> { // TODO unmock and add unit tests - return when (filter) { - RoomPollsFilterType.ACTIVE -> getActivePolls() - RoomPollsFilterType.ENDED -> emptyFlow() - }.map { it.sortedByDescending { poll -> poll.creationTimestamp } } + return getActivePolls() + .map { it.sortedByDescending { poll -> poll.creationTimestamp } } } private fun getActivePolls(): Flow> { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt index 3eb45c6144..939ee3ffa0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt @@ -22,4 +22,10 @@ sealed interface PollSummary { val creationTimestamp: Long, val title: String, ) : PollSummary + + data class EndedPoll( + val id: String, + val creationTimestamp: Long, + val title: String, + ) : PollSummary } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt index 5f074bdd6f..c18142a306 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsAction.kt @@ -18,6 +18,4 @@ package im.vector.app.features.roomprofile.polls import im.vector.app.core.platform.VectorViewModelAction -sealed interface RoomPollsAction : VectorViewModelAction { - data class SetFilter(val filter: RoomPollsFilterType) : RoomPollsAction -} +sealed interface RoomPollsAction : VectorViewModelAction diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index 5c150f4391..95aa5d0d95 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -67,6 +67,7 @@ class RoomPollsFragment : VectorBaseFragment() { tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> when (position) { 0 -> tab.text = getString(R.string.room_polls_active) + 1 -> tab.text = getString(R.string.room_polls_ended) } }.also { it.attach() } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt index 5472782079..2dc6fd4369 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt @@ -19,15 +19,19 @@ package im.vector.app.features.roomprofile.polls import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter import im.vector.app.features.roomprofile.polls.active.RoomActivePollsFragment +import im.vector.app.features.roomprofile.polls.ended.RoomEndedPollsFragment class RoomPollsPagerAdapter( private val fragment: Fragment ) : FragmentStateAdapter(fragment) { - override fun getItemCount() = 1 + override fun getItemCount() = 2 override fun createFragment(position: Int): Fragment { - return instantiateFragment(RoomActivePollsFragment::class.java.name) + return when (position) { + 0 -> instantiateFragment(RoomActivePollsFragment::class.java.name) + else -> instantiateFragment(RoomEndedPollsFragment::class.java.name) + } } private fun instantiateFragment(fragmentName: String): Fragment { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt index 7bc06894fa..95cb4717ca 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.roomprofile.polls -import androidx.annotation.VisibleForTesting import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -24,7 +23,6 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel -import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -40,24 +38,17 @@ class RoomPollsViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() - @VisibleForTesting - var pollsCollectionJob: Job? = null - - override fun handle(action: RoomPollsAction) { - when (action) { - is RoomPollsAction.SetFilter -> handleSetFilter(action.filter) - } + init { + observePolls() } - override fun onCleared() { - pollsCollectionJob = null - super.onCleared() - } - - private fun handleSetFilter(filter: RoomPollsFilterType) { - pollsCollectionJob?.cancel() - pollsCollectionJob = getPollsUseCase.execute(filter) + private fun observePolls() { + getPollsUseCase.execute() .onEach { setState { copy(polls = it) } } .launchIn(viewModelScope) } + + override fun handle(action: RoomPollsAction) { + // do nothing for now + } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index 61c7e961bd..dc735c79be 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -16,77 +16,19 @@ package im.vector.app.features.roomprofile.polls.active -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.view.isVisible -import com.airbnb.mvrx.parentFragmentViewModel -import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.extensions.cleanup -import im.vector.app.core.extensions.configureWith -import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.databinding.FragmentRoomPollsListBinding -import im.vector.app.features.roomprofile.polls.PollSummary -import im.vector.app.features.roomprofile.polls.RoomPollsAction import im.vector.app.features.roomprofile.polls.RoomPollsFilterType -import im.vector.app.features.roomprofile.polls.RoomPollsViewModel -import timber.log.Timber -import javax.inject.Inject +import im.vector.app.features.roomprofile.polls.list.RoomPollsListFragment @AndroidEntryPoint -class RoomActivePollsFragment : - VectorBaseFragment(), - RoomActivePollsController.Listener { +class RoomActivePollsFragment : RoomPollsListFragment() { - @Inject - lateinit var roomActivePollsController: RoomActivePollsController - - private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) - - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { - return FragmentRoomPollsListBinding.inflate(inflater, container, false) + override fun getEmptyListTitle(): String { + return getString(R.string.room_polls_active_no_item) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupList() - } - - private fun setupList() { - roomActivePollsController.listener = this - views.roomPollsList.configureWith(roomActivePollsController) - views.roomPollsEmptyTitle.text = getString(R.string.room_polls_active_no_item) - } - - override fun onDestroyView() { - cleanUpList() - super.onDestroyView() - } - - private fun cleanUpList() { - views.roomPollsList.cleanup() - roomActivePollsController.listener = null - } - - override fun onResume() { - super.onResume() - viewModel.handle(RoomPollsAction.SetFilter(RoomPollsFilterType.ACTIVE)) - } - - override fun invalidate() = withState(viewModel) { viewState -> - renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) - } - - private fun renderList(polls: List) { - roomActivePollsController.setData(polls) - views.roomPollsEmptyTitle.isVisible = polls.isEmpty() - } - - override fun onPollClicked(pollId: String) { - // TODO navigate to details - Timber.d("poll with id $pollId clicked") + override fun getRoomPollsFilter(): RoomPollsFilterType { + return RoomPollsFilterType.ACTIVE } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt new file mode 100644 index 0000000000..bad1a4e2da --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomprofile.polls.ended + +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R +import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.list.RoomPollsListFragment + +@AndroidEntryPoint +class RoomEndedPollsFragment : RoomPollsListFragment() { + + override fun getEmptyListTitle(): String { + return getString(R.string.room_polls_ended_no_item) + } + + override fun getRoomPollsFilter(): RoomPollsFilter { + return RoomPollsFilter.ENDED + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt similarity index 90% rename from vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt rename to vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt index 35b1ecd6e1..ac2b9cf3c0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/ActivePollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.roomprofile.polls.active +package im.vector.app.features.roomprofile.polls.list import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute @@ -26,7 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick @EpoxyModelClass -abstract class ActivePollItem : VectorEpoxyModel(R.layout.item_poll) { +abstract class RoomPollItem : VectorEpoxyModel(R.layout.item_poll) { @EpoxyAttribute lateinit var formattedDate: String diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt similarity index 50% rename from vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt rename to vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt index 7a7c818693..e24241f0af 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package im.vector.app.features.roomprofile.polls.active +package im.vector.app.features.roomprofile.polls.list import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.core.date.DateFormatKind @@ -22,9 +22,9 @@ import im.vector.app.core.date.VectorDateFormatter import im.vector.app.features.roomprofile.polls.PollSummary import javax.inject.Inject -class RoomActivePollsController @Inject constructor( +class RoomPollsController @Inject constructor( val dateFormatter: VectorDateFormatter, -) : TypedEpoxyController>() { +) : TypedEpoxyController>() { interface Listener { fun onPollClicked(pollId: String) @@ -32,20 +32,39 @@ class RoomActivePollsController @Inject constructor( var listener: Listener? = null - override fun buildModels(data: List?) { + override fun buildModels(data: List?) { if (data.isNullOrEmpty()) { return } - val host = this for (poll in data) { - activePollItem { - id(poll.id) - formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) - title(poll.title) - clickListener { - host.listener?.onPollClicked(poll.id) - } + when (poll) { + is PollSummary.ActivePoll -> buildActivePollItem(poll) + is PollSummary.EndedPoll -> buildEndedPollItem(poll) + } + } + } + + private fun buildActivePollItem(poll: PollSummary.ActivePoll) { + val host = this + roomPollItem { + id(poll.id) + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) + title(poll.title) + clickListener { + host.listener?.onPollClicked(poll.id) + } + } + } + + private fun buildEndedPollItem(poll: PollSummary.EndedPoll) { + val host = this + roomPollItem { + id(poll.id) + formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) + title(poll.title) + clickListener { + host.listener?.onPollClicked(poll.id) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt new file mode 100644 index 0000000000..f408f1c781 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.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.roomprofile.polls.list + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.view.isVisible +import com.airbnb.mvrx.parentFragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomPollsListBinding +import im.vector.app.features.roomprofile.polls.PollSummary +import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.RoomPollsViewModel +import timber.log.Timber +import javax.inject.Inject + +abstract class RoomPollsListFragment : + VectorBaseFragment(), + RoomPollsController.Listener { + + @Inject + lateinit var roomPollsController: RoomPollsController + + private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { + return FragmentRoomPollsListBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupList() + } + + abstract fun getEmptyListTitle(): String + + abstract fun getRoomPollsFilter(): RoomPollsFilter + + private fun setupList() { + roomPollsController.listener = this + views.roomPollsList.configureWith(roomPollsController) + views.roomPollsEmptyTitle.text = getEmptyListTitle() + } + + override fun onDestroyView() { + cleanUpList() + super.onDestroyView() + } + + private fun cleanUpList() { + views.roomPollsList.cleanup() + roomPollsController.listener = null + } + + override fun invalidate() = withState(viewModel) { viewState -> + when (getRoomPollsFilter()) { + RoomPollsFilter.ACTIVE -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) + RoomPollsFilter.ENDED -> renderList(viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)) + } + } + + private fun renderList(polls: List) { + roomPollsController.setData(polls) + views.roomPollsEmptyTitle.isVisible = polls.isEmpty() + } + + override fun onPollClicked(pollId: String) { + // TODO navigate to details + Timber.d("poll with id $pollId clicked") + } +} From 740591cd38a01d8bf469cac3d78cf162e4a71c89 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 17:31:23 +0100 Subject: [PATCH 216/246] Updating unit tests --- .../roomprofile/polls/RoomPollsViewModelTest.kt | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt index 0dce2dd6e0..9cca32c5e6 100644 --- a/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/roomprofile/polls/RoomPollsViewModelTest.kt @@ -23,7 +23,6 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.flow.flowOf -import org.amshove.kluent.shouldNotBeNull import org.junit.Rule import org.junit.Test @@ -45,28 +44,22 @@ class RoomPollsViewModelTest { } @Test - fun `given SetFilter action when handle then useCase is called with given filter and viewState is updated`() { + fun `given viewModel when created then polls list is observed and viewState is updated`() { // Given - val filter = RoomPollsFilterType.ACTIVE - val action = RoomPollsAction.SetFilter(filter = filter) val polls = listOf(givenAPollSummary()) - every { fakeGetPollsUseCase.execute(any()) } returns flowOf(polls) - val viewModel = createViewModel() + every { fakeGetPollsUseCase.execute() } returns flowOf(polls) val expectedViewState = initialState.copy(polls = polls) // When + val viewModel = createViewModel() val viewModelTest = viewModel.test() - viewModel.pollsCollectionJob = null - viewModel.handle(action) // Then viewModelTest .assertLatestState(expectedViewState) .finish() - viewModel.pollsCollectionJob.shouldNotBeNull() verify { - viewModel.pollsCollectionJob?.cancel() - fakeGetPollsUseCase.execute(filter) + fakeGetPollsUseCase.execute() } } From cf82486efa20613b7130399928c094eb031a790b Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 30 Dec 2022 17:38:55 +0100 Subject: [PATCH 217/246] Adding mocked data for ended polls --- .../roomprofile/polls/GetPollsUseCase.kt | 79 ++++++++++++------- .../features/roomprofile/polls/PollSummary.kt | 16 ++-- 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt index 06915c7b6a..7346f8769c 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -25,38 +25,59 @@ class GetPollsUseCase @Inject constructor() { fun execute(): Flow> { // TODO unmock and add unit tests - return getActivePolls() + return flowOf(getActivePolls() + getEndedPolls()) .map { it.sortedByDescending { poll -> poll.creationTimestamp } } } - private fun getActivePolls(): Flow> { - return flowOf( - listOf( - PollSummary.ActivePoll( - id = "id1", - // 2022/06/28 UTC+1 - creationTimestamp = 1656367200000, - title = "Which charity would you like to support?" - ), - PollSummary.ActivePoll( - id = "id2", - // 2022/06/26 UTC+1 - creationTimestamp = 1656194400000, - title = "Which sport should the pupils do this year?" - ), - PollSummary.ActivePoll( - id = "id3", - // 2022/06/24 UTC+1 - creationTimestamp = 1656021600000, - title = "What type of food should we have at the party?" - ), - PollSummary.ActivePoll( - id = "id4", - // 2022/06/22 UTC+1 - creationTimestamp = 1655848800000, - title = "What film should we show at the end of the year party?" - ), - ) + private fun getActivePolls(): List { + return listOf( + PollSummary.ActivePoll( + id = "id1", + // 2022/06/28 UTC+1 + creationTimestamp = 1656367200000, + title = "Which charity would you like to support?" + ), + PollSummary.ActivePoll( + id = "id2", + // 2022/06/26 UTC+1 + creationTimestamp = 1656194400000, + title = "Which sport should the pupils do this year?" + ), + PollSummary.ActivePoll( + id = "id3", + // 2022/06/24 UTC+1 + creationTimestamp = 1656021600000, + title = "What type of food should we have at the party?" + ), + PollSummary.ActivePoll( + id = "id4", + // 2022/06/22 UTC+1 + creationTimestamp = 1655848800000, + title = "What film should we show at the end of the year party?" + ), + ) + } + + private fun getEndedPolls(): List { + return listOf( + PollSummary.EndedPoll( + id = "id1-ended", + // 2022/06/28 UTC+1 + creationTimestamp = 1656367200000, + title = "Which charity would you like to support?" + ), + PollSummary.EndedPoll( + id = "id2-ended", + // 2022/06/26 UTC+1 + creationTimestamp = 1656194400000, + title = "Where should we do the offsite?" + ), + PollSummary.EndedPoll( + id = "id3-ended", + // 2022/06/24 UTC+1 + creationTimestamp = 1656021600000, + title = "What type of food should we have at the party?" + ), ) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt index 939ee3ffa0..12ac97dc02 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt @@ -17,15 +17,19 @@ package im.vector.app.features.roomprofile.polls sealed interface PollSummary { + val id: String + val creationTimestamp: Long + val title: String + data class ActivePoll( - val id: String, - val creationTimestamp: Long, - val title: String, + override val id: String, + override val creationTimestamp: Long, + override val title: String, ) : PollSummary data class EndedPoll( - val id: String, - val creationTimestamp: Long, - val title: String, + override val id: String, + override val creationTimestamp: Long, + override val title: String, ) : PollSummary } From 3deae1101c317375dbf1f14ddbcde8e40fa5a6c9 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Tue, 3 Jan 2023 17:32:41 +0100 Subject: [PATCH 218/246] Adding extra data for ended poll --- .../roomprofile/polls/GetPollsUseCase.kt | 37 +++++++++++++++++-- .../features/roomprofile/polls/PollSummary.kt | 4 ++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt index 7346f8769c..6f2a757ed7 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/GetPollsUseCase.kt @@ -16,6 +16,7 @@ package im.vector.app.features.roomprofile.polls +import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -64,19 +65,49 @@ class GetPollsUseCase @Inject constructor() { id = "id1-ended", // 2022/06/28 UTC+1 creationTimestamp = 1656367200000, - title = "Which charity would you like to support?" + title = "Which charity would you like to support?", + totalVotes = 22, + winnerOptions = listOf( + PollOptionViewState.PollEnded( + optionId = "id1", + optionAnswer = "Cancer research", + voteCount = 13, + votePercentage = 13 / 22.0, + isWinner = true, + ) + ), ), PollSummary.EndedPoll( id = "id2-ended", // 2022/06/26 UTC+1 creationTimestamp = 1656194400000, - title = "Where should we do the offsite?" + title = "Where should we do the offsite?", + totalVotes = 92, + winnerOptions = listOf( + PollOptionViewState.PollEnded( + optionId = "id1", + optionAnswer = "Hawaii", + voteCount = 43, + votePercentage = 43 / 92.0, + isWinner = true, + ) + ), ), PollSummary.EndedPoll( id = "id3-ended", // 2022/06/24 UTC+1 creationTimestamp = 1656021600000, - title = "What type of food should we have at the party?" + title = "What type of food should we have at the party?", + totalVotes = 22, + winnerOptions = listOf( + PollOptionViewState.PollEnded( + optionId = "id1", + optionAnswer = "Brazilian", + voteCount = 13, + votePercentage = 13 / 22.0, + isWinner = true, + ) + ), ), ) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt index 12ac97dc02..f24ac8b8a6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/PollSummary.kt @@ -16,6 +16,8 @@ package im.vector.app.features.roomprofile.polls +import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState + sealed interface PollSummary { val id: String val creationTimestamp: Long @@ -31,5 +33,7 @@ sealed interface PollSummary { override val id: String, override val creationTimestamp: Long, override val title: String, + val totalVotes: Int, + val winnerOptions: List, ) : PollSummary } From 1cc26449f3f9145abe79e105a9635aa1f4152dde Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:12:34 +0100 Subject: [PATCH 219/246] Renaming some ui fields --- .../features/roomprofile/polls/list/RoomPollItem.kt | 4 ++-- vector/src/main/res/layout/item_poll.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt index ac2b9cf3c0..633162f6eb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt @@ -45,7 +45,7 @@ abstract class RoomPollItem : VectorEpoxyModel(R.layout.ite } class Holder : VectorEpoxyHolder() { - val date by bind(R.id.pollActiveDate) - val title by bind(R.id.pollActiveTitle) + val date by bind(R.id.pollDate) + val title by bind(R.id.pollTitle) } } diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 956ecf9b3c..8e9fa54a0f 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -7,7 +7,7 @@ android:foreground="?selectableItemBackground"> From 05363dc8ca26609ff41f746869a720ccb7da6135 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:30:57 +0100 Subject: [PATCH 220/246] Adding winner option views for ended poll items --- .../features/roomprofile/polls/list/RoomPollItem.kt | 13 +++++++++++++ .../roomprofile/polls/list/RoomPollsController.kt | 1 + vector/src/main/res/layout/item_poll.xml | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt index 633162f6eb..fd4e36159e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt @@ -16,6 +16,7 @@ package im.vector.app.features.roomprofile.polls.list +import android.widget.LinearLayout import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass @@ -24,6 +25,8 @@ import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick +import im.vector.app.features.home.room.detail.timeline.item.PollOptionView +import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState @EpoxyModelClass abstract class RoomPollItem : VectorEpoxyModel(R.layout.item_poll) { @@ -34,6 +37,9 @@ abstract class RoomPollItem : VectorEpoxyModel(R.layout.ite @EpoxyAttribute lateinit var title: String + @EpoxyAttribute + var winnerOptions: List = emptyList() + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var clickListener: ClickListener? = null @@ -42,10 +48,17 @@ abstract class RoomPollItem : VectorEpoxyModel(R.layout.ite holder.view.onClick(clickListener) holder.date.text = formattedDate holder.title.text = title + holder.winnerOptions.removeAllViews() + for (winnerOption in winnerOptions) { + val optionView = PollOptionView(holder.view.context) + holder.winnerOptions.addView(optionView) + optionView.render(winnerOption) + } } class Holder : VectorEpoxyHolder() { val date by bind(R.id.pollDate) val title by bind(R.id.pollTitle) + val winnerOptions by bind(R.id.pollWinnerOptionsContainer) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt index e24241f0af..c6288aac8b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt @@ -63,6 +63,7 @@ class RoomPollsController @Inject constructor( id(poll.id) formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) title(poll.title) + winnerOptions(poll.winnerOptions) clickListener { host.listener?.onPollClicked(poll.id) } diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 8e9fa54a0f..9563f3d52a 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -42,4 +42,16 @@ app:layout_constraintTop_toBottomOf="@id/pollDate" tools:text="Which sport should the pupils do this year?" /> + + From a5d076a28a2c82483cdaea9114f1e0cc0cc561da Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:49:07 +0100 Subject: [PATCH 221/246] Adding total votes status for ended poll items --- .../features/roomprofile/polls/list/RoomPollItem.kt | 8 ++++++++ .../roomprofile/polls/list/RoomPollsController.kt | 4 ++++ vector/src/main/res/layout/item_poll.xml | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt index fd4e36159e..da00fedddb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollItem.kt @@ -18,6 +18,7 @@ package im.vector.app.features.roomprofile.polls.list import android.widget.LinearLayout import android.widget.TextView +import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R @@ -25,6 +26,7 @@ import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.home.room.detail.timeline.item.PollOptionView import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState @@ -40,6 +42,9 @@ abstract class RoomPollItem : VectorEpoxyModel(R.layout.ite @EpoxyAttribute var winnerOptions: List = emptyList() + @EpoxyAttribute + var totalVotesStatus: String? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var clickListener: ClickListener? = null @@ -49,16 +54,19 @@ abstract class RoomPollItem : VectorEpoxyModel(R.layout.ite holder.date.text = formattedDate holder.title.text = title holder.winnerOptions.removeAllViews() + holder.winnerOptions.isVisible = winnerOptions.isNotEmpty() for (winnerOption in winnerOptions) { val optionView = PollOptionView(holder.view.context) holder.winnerOptions.addView(optionView) optionView.render(winnerOption) } + holder.totalVotes.setTextOrHide(totalVotesStatus) } class Holder : VectorEpoxyHolder() { val date by bind(R.id.pollDate) val title by bind(R.id.pollTitle) val winnerOptions by bind(R.id.pollWinnerOptionsContainer) + val totalVotes by bind(R.id.pollTotalVotes) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt index c6288aac8b..f0e3b6b9a4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsController.kt @@ -17,13 +17,16 @@ package im.vector.app.features.roomprofile.polls.list import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter +import im.vector.app.core.resources.StringProvider import im.vector.app.features.roomprofile.polls.PollSummary import javax.inject.Inject class RoomPollsController @Inject constructor( val dateFormatter: VectorDateFormatter, + val stringProvider: StringProvider, ) : TypedEpoxyController>() { interface Listener { @@ -64,6 +67,7 @@ class RoomPollsController @Inject constructor( formattedDate(host.dateFormatter.format(poll.creationTimestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)) title(poll.title) winnerOptions(poll.winnerOptions) + totalVotesStatus(host.stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, poll.totalVotes, poll.totalVotes)) clickListener { host.listener?.onPollClicked(poll.id) } diff --git a/vector/src/main/res/layout/item_poll.xml b/vector/src/main/res/layout/item_poll.xml index 9563f3d52a..17f3b5abf5 100644 --- a/vector/src/main/res/layout/item_poll.xml +++ b/vector/src/main/res/layout/item_poll.xml @@ -54,4 +54,16 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/pollTitle" /> + + From 9b5fda2689531063847707804100be2576990afa Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:45:35 +0100 Subject: [PATCH 222/246] Fix after rebase --- .../roomprofile/polls/ended/RoomEndedPollsFragment.kt | 6 +++--- .../roomprofile/polls/list/RoomPollsListFragment.kt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt index bad1a4e2da..add7096409 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt @@ -18,7 +18,7 @@ package im.vector.app.features.roomprofile.polls.ended import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.RoomPollsFilterType import im.vector.app.features.roomprofile.polls.list.RoomPollsListFragment @AndroidEntryPoint @@ -28,7 +28,7 @@ class RoomEndedPollsFragment : RoomPollsListFragment() { return getString(R.string.room_polls_ended_no_item) } - override fun getRoomPollsFilter(): RoomPollsFilter { - return RoomPollsFilter.ENDED + override fun getRoomPollsFilter(): RoomPollsFilterType { + return RoomPollsFilterType.ENDED } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt index f408f1c781..f6aa59f447 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt @@ -28,7 +28,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary -import im.vector.app.features.roomprofile.polls.RoomPollsFilter +import im.vector.app.features.roomprofile.polls.RoomPollsFilterType import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import timber.log.Timber import javax.inject.Inject @@ -53,7 +53,7 @@ abstract class RoomPollsListFragment : abstract fun getEmptyListTitle(): String - abstract fun getRoomPollsFilter(): RoomPollsFilter + abstract fun getRoomPollsFilter(): RoomPollsFilterType private fun setupList() { roomPollsController.listener = this @@ -73,8 +73,8 @@ abstract class RoomPollsListFragment : override fun invalidate() = withState(viewModel) { viewState -> when (getRoomPollsFilter()) { - RoomPollsFilter.ACTIVE -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) - RoomPollsFilter.ENDED -> renderList(viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)) + RoomPollsFilterType.ACTIVE -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) + RoomPollsFilterType.ENDED -> renderList(viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)) } } From b8da53b3bb4a7e62e0fa20aeaab425c4782742ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 11:56:11 +0000 Subject: [PATCH 223/246] Bump checker from 3.27.0 to 3.29.0 (#7903) Bumps [checker](https://github.com/typetools/checker-framework) from 3.27.0 to 3.29.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.27.0...checker-framework-3.29.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- vector/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/build.gradle b/vector/build.gradle index 83af7ecc04..91d2a8c46a 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -308,7 +308,7 @@ dependencies { // Fix issue with Jitsi. Inspired from https://github.com/android/android-test/issues/861#issuecomment-872067868 // Error was lots of `Duplicate class org.checkerframework.common.reflection.qual.MethodVal found in modules jetified-checker-3.1 (org.checkerframework:checker:3.1.1) and jetified-checker-qual-3.12.0 (org.checkerframework:checker-qual:3.12.0) //noinspection GradleDependency Cannot use latest 3.15.0 since it required min API 26. - implementation "org.checkerframework:checker:3.27.0" + implementation "org.checkerframework:checker:3.29.0" androidTestImplementation libs.androidx.testCore androidTestImplementation libs.androidx.testRunner From 85cfa433d9e15362c0b907d19e253c01cff665c5 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL <46314705+mnaturel@users.noreply.github.com> Date: Fri, 6 Jan 2023 14:13:58 +0100 Subject: [PATCH 224/246] Using ordinal of enum to render tabs --- .../features/roomprofile/polls/RoomPollsFragment.kt | 4 ++-- .../roomprofile/polls/RoomPollsPagerAdapter.kt | 7 ++++--- .../polls/{RoomPollsFilterType.kt => RoomPollsType.kt} | 2 +- .../polls/active/RoomActivePollsFragment.kt | 6 +++--- .../roomprofile/polls/ended/RoomEndedPollsFragment.kt | 6 +++--- .../roomprofile/polls/list/RoomPollsListFragment.kt | 10 +++++----- 6 files changed, 18 insertions(+), 17 deletions(-) rename vector/src/main/java/im/vector/app/features/roomprofile/polls/{RoomPollsFilterType.kt => RoomPollsType.kt} (95%) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt index 95aa5d0d95..9f7e704135 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFragment.kt @@ -66,8 +66,8 @@ class RoomPollsFragment : VectorBaseFragment() { tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> when (position) { - 0 -> tab.text = getString(R.string.room_polls_active) - 1 -> tab.text = getString(R.string.room_polls_ended) + RoomPollsType.ACTIVE.ordinal -> tab.text = getString(R.string.room_polls_active) + RoomPollsType.ENDED.ordinal -> tab.text = getString(R.string.room_polls_ended) } }.also { it.attach() } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt index 2dc6fd4369..c60fc5de27 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsPagerAdapter.kt @@ -25,12 +25,13 @@ class RoomPollsPagerAdapter( private val fragment: Fragment ) : FragmentStateAdapter(fragment) { - override fun getItemCount() = 2 + override fun getItemCount() = RoomPollsType.values().size override fun createFragment(position: Int): Fragment { return when (position) { - 0 -> instantiateFragment(RoomActivePollsFragment::class.java.name) - else -> instantiateFragment(RoomEndedPollsFragment::class.java.name) + RoomPollsType.ACTIVE.ordinal -> instantiateFragment(RoomActivePollsFragment::class.java.name) + RoomPollsType.ENDED.ordinal -> instantiateFragment(RoomEndedPollsFragment::class.java.name) + else -> throw IllegalArgumentException("position should be between 0 and ${itemCount - 1}, while it was $position") } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsType.kt similarity index 95% rename from vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt rename to vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsType.kt index 39f1163536..134ef9a195 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsFilterType.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/RoomPollsType.kt @@ -16,7 +16,7 @@ package im.vector.app.features.roomprofile.polls -enum class RoomPollsFilterType { +enum class RoomPollsType { ACTIVE, ENDED, } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt index dc735c79be..1c6a03c480 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/active/RoomActivePollsFragment.kt @@ -18,7 +18,7 @@ package im.vector.app.features.roomprofile.polls.active import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.features.roomprofile.polls.RoomPollsFilterType +import im.vector.app.features.roomprofile.polls.RoomPollsType import im.vector.app.features.roomprofile.polls.list.RoomPollsListFragment @AndroidEntryPoint @@ -28,7 +28,7 @@ class RoomActivePollsFragment : RoomPollsListFragment() { return getString(R.string.room_polls_active_no_item) } - override fun getRoomPollsFilter(): RoomPollsFilterType { - return RoomPollsFilterType.ACTIVE + override fun getRoomPollsType(): RoomPollsType { + return RoomPollsType.ACTIVE } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt index add7096409..8dd0cadadf 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/ended/RoomEndedPollsFragment.kt @@ -18,7 +18,7 @@ package im.vector.app.features.roomprofile.polls.ended import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.features.roomprofile.polls.RoomPollsFilterType +import im.vector.app.features.roomprofile.polls.RoomPollsType import im.vector.app.features.roomprofile.polls.list.RoomPollsListFragment @AndroidEntryPoint @@ -28,7 +28,7 @@ class RoomEndedPollsFragment : RoomPollsListFragment() { return getString(R.string.room_polls_ended_no_item) } - override fun getRoomPollsFilter(): RoomPollsFilterType { - return RoomPollsFilterType.ENDED + override fun getRoomPollsType(): RoomPollsType { + return RoomPollsType.ENDED } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt index f6aa59f447..0d97bd8dcb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/polls/list/RoomPollsListFragment.kt @@ -28,7 +28,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.features.roomprofile.polls.PollSummary -import im.vector.app.features.roomprofile.polls.RoomPollsFilterType +import im.vector.app.features.roomprofile.polls.RoomPollsType import im.vector.app.features.roomprofile.polls.RoomPollsViewModel import timber.log.Timber import javax.inject.Inject @@ -53,7 +53,7 @@ abstract class RoomPollsListFragment : abstract fun getEmptyListTitle(): String - abstract fun getRoomPollsFilter(): RoomPollsFilterType + abstract fun getRoomPollsType(): RoomPollsType private fun setupList() { roomPollsController.listener = this @@ -72,9 +72,9 @@ abstract class RoomPollsListFragment : } override fun invalidate() = withState(viewModel) { viewState -> - when (getRoomPollsFilter()) { - RoomPollsFilterType.ACTIVE -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) - RoomPollsFilterType.ENDED -> renderList(viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)) + when (getRoomPollsType()) { + RoomPollsType.ACTIVE -> renderList(viewState.polls.filterIsInstance(PollSummary.ActivePoll::class.java)) + RoomPollsType.ENDED -> renderList(viewState.polls.filterIsInstance(PollSummary.EndedPoll::class.java)) } } From 0dd1abb9262a9ecf28ac85c99958e238d1459a95 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 6 Dec 2022 13:02:02 +0100 Subject: [PATCH 225/246] Rename method --- .../app/features/crypto/quads/SharedSecureStorageActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index d393636a8e..aea87beea9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -59,7 +59,7 @@ class SharedSecureStorageActivity : views.toolbar.visibility = View.GONE - viewModel.observeViewEvents { observeViewEvents(it) } + viewModel.observeViewEvents { onViewEvents(it) } viewModel.onEach { renderState(it) } } @@ -85,7 +85,7 @@ class SharedSecureStorageActivity : showFragment(fragment) } - private fun observeViewEvents(it: SharedSecureStorageViewEvent?) { + private fun onViewEvents(it: SharedSecureStorageViewEvent) { when (it) { is SharedSecureStorageViewEvent.Dismiss -> { finish() From 9c79d234440310bf41e4964c78dc48e8bbb89c15 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 16 Dec 2022 21:02:33 +0100 Subject: [PATCH 226/246] Ensure event are not sent if the lifecycle state is not RESUMED --- .../app/core/platform/VectorBaseActivity.kt | 22 ++++++++++++------- .../VectorBaseBottomSheetDialogFragment.kt | 21 ++++++++++++------ .../app/core/platform/VectorBaseFragment.kt | 22 ++++++++++++------- .../im/vector/app/features/MainActivity.kt | 8 +++---- .../media/VectorAttachmentViewerActivity.kt | 16 +++++++++----- .../settings/VectorSettingsBaseFragment.kt | 22 +++++++++++++------ 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 4e5116eda9..a87eb92b13 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -41,6 +41,7 @@ import androidx.fragment.app.FragmentManager import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.preference.PreferenceManager import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView @@ -91,6 +92,7 @@ import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.themes.ThemeUtils import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.GlobalError @@ -123,14 +125,18 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver protected val viewModelProvider get() = ViewModelProvider(this, viewModelFactory) - fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { - viewEvents - .stream() - .onEach { - hideWaitingView() - observer(it) - } - .launchIn(lifecycleScope) + fun VectorViewModel<*, *, T>.observeViewEvents( + observer: (T) -> Unit, + ) { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewEvents.stream() + .collect { + hideWaitingView() + observer(it) + } + } + } } var toolbar: ToolbarConfig? = null diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index ec6f3288f8..ad7a86c899 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -26,8 +26,10 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.annotation.CallSuper import androidx.annotation.FloatRange +import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -43,6 +45,7 @@ import im.vector.app.features.analytics.plan.MobileScreen import io.github.hyuwah.draggableviewlib.Utils import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import reactivecircus.flowbinding.android.view.clicks import timber.log.Timber @@ -199,12 +202,16 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe * ViewEvents * ========================================================================================== */ - protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { - viewEvents - .stream() - .onEach { - observer(it) - } - .launchIn(viewLifecycleOwner.lifecycleScope) + protected fun VectorViewModel<*, *, T>.observeViewEvents( + observer: (T) -> Unit, + ) { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewEvents.stream() + .collect { + observer(it) + } + } + } } } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 8fe2d33f6a..9f79db9c66 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -34,6 +34,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView import com.bumptech.glide.util.Util.assertMainThread @@ -53,6 +54,7 @@ import im.vector.app.features.navigation.Navigator import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import reactivecircus.flowbinding.android.view.clicks import timber.log.Timber @@ -272,14 +274,18 @@ abstract class VectorBaseFragment : Fragment(), MavericksView * ViewEvents * ========================================================================================== */ - protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { - viewEvents - .stream() - .onEach { - dismissLoadingDialog() - observer(it) - } - .launchIn(viewLifecycleOwner.lifecycleScope) + protected fun VectorViewModel<*, *, T>.observeViewEvents( + observer: (T) -> Unit, + ) { + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewEvents.stream() + .collect { + dismissLoadingDialog() + observer(it) + } + } + } } /* ========================================================================================== 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 8ce375122e..cffb1577cf 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -55,8 +55,6 @@ import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.ui.UiStateRepository import im.vector.lib.core.utils.compat.getParcelableExtraCompat import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize @@ -142,9 +140,9 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity startAppViewModel.onEach { renderState(it) } - startAppViewModel.viewEvents.stream() - .onEach(::handleViewEvents) - .launchIn(lifecycleScope) + startAppViewModel.observeViewEvents { + handleViewEvents(it) + } startAppViewModel.handle(StartAppAction.StartApp) } diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index 089fdcebd4..9f9488e35d 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -29,7 +29,9 @@ import androidx.core.transition.addListener import androidx.core.view.ViewCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.transition.Transition import com.airbnb.mvrx.viewModel import dagger.hilt.android.AndroidEntryPoint @@ -50,8 +52,6 @@ import im.vector.lib.attachmentviewer.AttachmentViewerActivity import im.vector.lib.core.utils.compat.getParcelableArrayListExtraCompat import im.vector.lib.core.utils.compat.getParcelableExtraCompat import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize @@ -239,10 +239,14 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt } private fun observeViewEvents() { - viewModel.viewEvents - .stream() - .onEach(::handleViewEvents) - .launchIn(lifecycleScope) + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewModel + .viewEvents + .stream() + .collect(::handleViewEvents) + } + } } private fun handleViewEvents(event: VectorAttachmentViewerViewEvents) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 38ba949a49..6299d8962d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -20,7 +20,9 @@ import android.content.Context import android.os.Bundle import android.view.View import androidx.annotation.CallSuper +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.preference.PreferenceFragmentCompat import com.airbnb.mvrx.MavericksView import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -35,6 +37,7 @@ import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import reactivecircus.flowbinding.android.view.clicks import timber.log.Timber @@ -66,13 +69,18 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick * ViewEvents * ========================================================================================== */ - protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { - viewEvents - .stream() - .onEach { - observer(it) - } - .launchIn(viewLifecycleOwner.lifecycleScope) + protected fun VectorViewModel<*, *, T>.observeViewEvents( + observer: (T) -> Unit, + ) { + lifecycleScope.launch { + repeatOnLifecycle(state) { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewEvents.stream() + .collect { + observer(it) + } + } + } } /* ========================================================================================== From 71bd4f457a8093683c6b9d046352e032c92d21eb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 7 Dec 2022 17:48:25 +0100 Subject: [PATCH 227/246] Ensure posted events from the ViewModel are consumed (once) by the UI Inspired from https://github.com/Kotlin/kotlinx.coroutines/issues/3002 --- .../app/core/platform/VectorBaseActivity.kt | 4 +- .../VectorBaseBottomSheetDialogFragment.kt | 4 +- .../app/core/platform/VectorBaseFragment.kt | 4 +- .../app/core/platform/VectorViewModel.kt | 9 +-- .../im/vector/app/core/utils/SharedEvent.kt | 58 +++++++++++++++++++ .../media/VectorAttachmentViewerActivity.kt | 3 +- .../settings/VectorSettingsBaseFragment.kt | 5 +- 7 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/utils/SharedEvent.kt diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index a87eb92b13..1e29dfff5e 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -128,9 +128,11 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver fun VectorViewModel<*, *, T>.observeViewEvents( observer: (T) -> Unit, ) { + val tag = this@VectorBaseActivity::class.simpleName.toString() lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { - viewEvents.stream() + viewEvents + .stream(tag) .collect { hideWaitingView() observer(it) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index ad7a86c899..a44fb1c9ac 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -205,9 +205,11 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe protected fun VectorViewModel<*, *, T>.observeViewEvents( observer: (T) -> Unit, ) { + val tag = this@VectorBaseBottomSheetDialogFragment::class.simpleName.toString() lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { - viewEvents.stream() + viewEvents + .stream(tag) .collect { observer(it) } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 9f79db9c66..a82cef54e5 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -277,9 +277,11 @@ abstract class VectorBaseFragment : Fragment(), MavericksView protected fun VectorViewModel<*, *, T>.observeViewEvents( observer: (T) -> Unit, ) { + val tag = this@VectorBaseFragment::class.simpleName.toString() lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { - viewEvents.stream() + viewEvents + .stream(tag) .collect { dismissLoadingDialog() observer(it) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt index c9d58f9545..3dd38c455f 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt @@ -18,15 +18,16 @@ package im.vector.app.core.platform import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModel -import im.vector.app.core.utils.DataSource -import im.vector.app.core.utils.PublishDataSource +import im.vector.app.core.utils.EventQueue +import im.vector.app.core.utils.SharedEvents abstract class VectorViewModel(initialState: S) : MavericksViewModel(initialState) { // Used to post transient events to the View - protected val _viewEvents = PublishDataSource() - val viewEvents: DataSource = _viewEvents + protected val _viewEvents = EventQueue(capacity = 64) + val viewEvents: SharedEvents + get() = _viewEvents abstract fun handle(action: VA) } diff --git a/vector/src/main/java/im/vector/app/core/utils/SharedEvent.kt b/vector/src/main/java/im/vector/app/core/utils/SharedEvent.kt new file mode 100644 index 0000000000..e712769c48 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/utils/SharedEvent.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.utils + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.transform +import java.util.concurrent.CopyOnWriteArraySet + +interface SharedEvents { + fun stream(consumerId: String): Flow +} + +class EventQueue(capacity: Int) : SharedEvents { + + private val innerQueue = MutableSharedFlow>(replay = capacity) + + fun post(event: T) { + innerQueue.tryEmit(OneTimeEvent(event)) + } + + override fun stream(consumerId: String): Flow = innerQueue.filterNotHandledBy(consumerId) +} + +/** + * Event designed to be delivered only once to a concrete entity, + * but it can also be delivered to multiple different entities. + * + * Keeps track of who has already handled its content. + */ +private class OneTimeEvent(private val content: T) { + + private val handlers = CopyOnWriteArraySet() + + /** + * @param asker Used to identify, whether this "asker" has already handled this Event. + * @return Event content or null if it has been already handled by asker + */ + fun getIfNotHandled(asker: String): T? = if (handlers.add(asker)) content else null +} + +private fun Flow>.filterNotHandledBy(consumerId: String): Flow = transform { event -> + event.getIfNotHandled(consumerId)?.let { emit(it) } +} diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index 9f9488e35d..0d240b376b 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -239,11 +239,12 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt } private fun observeViewEvents() { + val tag = this::class.simpleName.toString() lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { viewModel .viewEvents - .stream() + .stream(tag) .collect(::handleViewEvents) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 6299d8962d..724807a81e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -72,10 +72,11 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick protected fun VectorViewModel<*, *, T>.observeViewEvents( observer: (T) -> Unit, ) { + val tag = this@VectorSettingsBaseFragment::class.simpleName.toString() lifecycleScope.launch { - repeatOnLifecycle(state) { repeatOnLifecycle(Lifecycle.State.RESUMED) { - viewEvents.stream() + viewEvents + .stream(tag) .collect { observer(it) } From 9768430d5c19cc78a7d21c7dce375bb39890d26b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 19 Dec 2022 18:32:07 +0100 Subject: [PATCH 228/246] Fix test compilation issue --- vector/src/test/java/im/vector/app/test/Extensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/test/java/im/vector/app/test/Extensions.kt b/vector/src/test/java/im/vector/app/test/Extensions.kt index 2fbab3b71b..0b1a22f75c 100644 --- a/vector/src/test/java/im/vector/app/test/Extensions.kt +++ b/vector/src/test/java/im/vector/app/test/Extensions.kt @@ -28,7 +28,7 @@ fun String.trimIndentOneLine() = trimIndent().replace("\n", "") fun VectorViewModel.test(): ViewModelTest { val testResultCollectingScope = CoroutineScope(Dispatchers.Unconfined) val state = stateFlow.test(testResultCollectingScope) - val viewEvents = viewEvents.stream().test(testResultCollectingScope) + val viewEvents = viewEvents.stream("test").test(testResultCollectingScope) return ViewModelTest(state, viewEvents) } From 7b1724f6dd1aa3651fc7a36890565cf9d213aa27 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 Jan 2023 15:13:01 +0100 Subject: [PATCH 229/246] changelog --- changelog.d/7724.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7724.bugfix diff --git a/changelog.d/7724.bugfix b/changelog.d/7724.bugfix new file mode 100644 index 0000000000..685f7ad4e2 --- /dev/null +++ b/changelog.d/7724.bugfix @@ -0,0 +1 @@ + Observe ViewEvents only when resumed and ensure ViewEvents are not lost. From ea924642ce0e4eca0537f5f752e63c27d5fe5e3e Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Thu, 5 Jan 2023 16:51:43 +0000 Subject: [PATCH 230/246] Translated using Weblate (Danish) Currently translated at 10.2% (264 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/da/ --- .../src/main/res/values-da/strings.xml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/library/ui-strings/src/main/res/values-da/strings.xml b/library/ui-strings/src/main/res/values-da/strings.xml index 13d53b7bb2..35c93949f9 100644 --- a/library/ui-strings/src/main/res/values-da/strings.xml +++ b/library/ui-strings/src/main/res/values-da/strings.xml @@ -39,7 +39,6 @@ Telefonnummer Invitation til rum %1$s og %2$s - Tomt rum Lyst Tema Mørkt Tema @@ -82,7 +81,6 @@ Kun Matrix kontakter Ingen resultater Rum - Send logfiler Send crashlogfiler Send screenshot @@ -110,10 +108,8 @@ Dette ligner ikke en gyldig emailadresse Den emailadresse er allerede i brug. Glemt adgangskode? - Denne Home Server vil gerne være sikker på du ikke er en robot Kunne ikke verificere emailadresse: vær sikker på du klikkede på linket i emailen - Skriv gyldig URL Fejlformet JSON Indeholdt ikke gyldig JSON @@ -134,15 +130,10 @@ Opkald I Gang Den anden side tog den ikke. Information - - ${app_name} skal bruge tilladelse til at bruge din mikrofon for at lave lydopkald. - ${app_name} skal bruge tilladelse til at bruge dit kamera og din mikrofon for at lave videoopkald. Giv venligst tilladelse ved næste pop-up for at lave opkaldet. - - JA NEJ Fortsæt @@ -150,7 +141,6 @@ Giv venligst tilladelse ved næste pop-up for at lave opkaldet. Forbind Afvis Spring til første ulæste besked. - Forlad rum Er du sikker på at du vil forlade rummet? DIREKTE CHATS @@ -163,7 +153,7 @@ Giv venligst tilladelse ved næste pop-up for at lave opkaldet. Du vil ikke kunne omgøre denne ændring da du forfremmer brugeren til at have samme magt niveau som dig selv. Er du sikker? %s skriver… - "%1$s & %2$s skriver…" + %1$s & %2$s skriver… %1$s, %2$s og andre skriver… Du har ikke tilladelse til at skrive i dette rum Stol på @@ -186,7 +176,6 @@ Er du sikker? %d medlemsændringer Medlemsoversigt - 1 medlem %d medlemmer @@ -199,8 +188,6 @@ Er du sikker? Søg Filtrer medlemmer i rum Ingen resultater - - Alle meddelelser Opret genvej på startskærm Profilbillede @@ -291,4 +278,4 @@ Er du sikker? %1$s oprettede rummet Din invitation Forbind denne email med din konto - + \ No newline at end of file From 725722d3f29b42e033925491c8e6ca1d492aaf0e Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Thu, 5 Jan 2023 16:14:10 +0000 Subject: [PATCH 231/246] Translated using Weblate (Esperanto) Currently translated at 76.0% (1960 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/eo/ --- library/ui-strings/src/main/res/values-eo/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/ui-strings/src/main/res/values-eo/strings.xml b/library/ui-strings/src/main/res/values-eo/strings.xml index f536ca00f9..4521e840a6 100644 --- a/library/ui-strings/src/main/res/values-eo/strings.xml +++ b/library/ui-strings/src/main/res/values-eo/strings.xml @@ -718,8 +718,8 @@ Bonvolu enigi la URL-on de identiga servilo Ne povis konektiĝi al identiga servilo Enigu URL-on de identiga servilo - Ni sendis al vi konfirman retleteron al %s, bonvolu unue kontroli vian retpoŝton kaj klaki la konfirman ligilon - Ni sendis al vi konfirman retleteron al %s; kontrolu vian retpoŝton kaj klaku la konfirman ligilon + Ni sendis retleteron al %s, bonvolu unue kontroli vian retpoŝton kaj klaki la konfirman ligilon + Ni sendis retleteron al %s; kontrolu vian retpoŝton kaj klaku la konfirman ligilon Troveblaj telefonnumeroj Malkonekto de via identiga servilo signifas, ke vi ne estos trovebla de aliaj uzantoj kaj ne povos inviti aliulojn per retpoŝtadreso aŭ telefono. Elektebloj pri trovado aperos post aldono de telefonnumero. @@ -2201,4 +2201,4 @@ Sonorante… Aroj - Iom uzantoj reatentita - + \ No newline at end of file From 3098ec140d384a7705d384444c30e7d8a44b81df Mon Sep 17 00:00:00 2001 From: overtinkering Date: Thu, 5 Jan 2023 18:02:33 +0000 Subject: [PATCH 232/246] Translated using Weblate (Spanish) Currently translated at 90.7% (2338 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/es/ --- .../src/main/res/values-es/strings.xml | 109 ++++++++++-------- 1 file changed, 62 insertions(+), 47 deletions(-) diff --git a/library/ui-strings/src/main/res/values-es/strings.xml b/library/ui-strings/src/main/res/values-es/strings.xml index e07c21d6a5..c06442b5d0 100644 --- a/library/ui-strings/src/main/res/values-es/strings.xml +++ b/library/ui-strings/src/main/res/values-es/strings.xml @@ -50,7 +50,7 @@ %1$s ha invitado a %2$s. Razón: %3$s %1$s te ha invitado. Razón: %2$s %1$s se ha unido. Razón: %2$s - %1$s se ha ido. Razón: %2$s + %1$s dejó la sala. Razón: %2$s %1$s ha rechadazo la invitación. Razón: %2$s %1$s expulsó a %2$s. Razón: %3$s %1$s ha baneado a %2$s. Razón: %3$s @@ -81,17 +81,17 @@ %1$s ha permitido que los invitados se unan a la sala. %1$s ha impedido que los invitados se unan a la sala. %1$s ha activado el cifrado Extremo-a-Extremo. - %1$s ha activado el cifrado Extremo-a-Extremo (algoritmo no reconocido %2$s). + %1$s ha activado el cifrado extremo-a-extremo (algoritmo no reconocido %2$s). Tu invitación %1$s creó la sala Creaste la sala Invitaste a %1$s Te uniste a la Sala - Dejaste la Sala + Dejaste la sala Rechazaste la invitación Tu pateaste a %1$s Tu desbanaste a %1$s - Usted prohibió a %1$s + Excluiste a %1$s Retiró la invitación de %1$s\'s Cambiaste tu avatar Establece su nombre de visualización en %1$s @@ -152,10 +152,10 @@ Agregaste %1$s y quitaste %2$s como direcciones para esta sala. Estableciste la dirección principal de esta sala en %1$s. Quitaste la dirección principal de esta sala. - Ha permitido que los invitados se unan a la sala. - Ha impedido que los invitados se unan a la sala. + Has permitido que los invitados se unan a la sala. + Has impedido que los invitados se unan a la sala. Has activado el cifrado Extremo-a-Extremo. - Has activado el cifrado Extremo-a-Extremo (algoritmo %1$s no reconocido). + Has activado el cifrado extremo-a-extremo (algoritmo %1$s no reconocido). Has impedido que invitados se unan a la sala. Has permitido a invitados unirse aquí. Te has ido. Razón: %1$s @@ -163,7 +163,7 @@ Has invitado a %1$s Has actualizado aquí. Has hecho futuros mensajes visibles a %1$s - Te saliste de la sala + Has dejado la sala Te uniste Creaste la conversación %1$s ha impedido que invitados se unan a la sala. @@ -255,7 +255,7 @@ Salas y Grupos Filtrar salas Invitaciones - Prioridad baja + Baja prioridad Conversaciones Solo contactos de Matrix No hay resultados @@ -429,7 +429,7 @@ Importar Cifrar solo a sesiones verificadas Nunca enviar mensajes cifrados a sesiones sin verificar desde esta sesión. - SIN Verificar + Sin Verificar Verificado Verificar Para verificar que esta sesión es confiable, por favor contacta a su dueño por algún otro medio (ej. cara a cara o por teléfono) y pregúntale si la clave que ve en sus Ajustes de Usuario para esta sesión coincide con la clave a continuación: @@ -819,7 +819,7 @@ La copia de seguridad tiene una firma valida de la sesión no verificada %s La copia de seguridad tiene una firma inválida de la sesión verificada %s La copia de seguridad tiene una firma inválida de la sesión no verificada %s - Para usar la copia de seguridad de la clave en esta sesión introduzca su contraseña o su clave de recuperación ahora. + Para usar la copia de seguridad de la clave en esta sesión introduce tu contraseña o tu clave de recuperación ahora. ¿Deseas borrar tus claves de cifrado guardadas en el servidor\? No podrás usar tu clave de recuperación para leer el historial de mensajes cifrados. Reproducir sonido de cámara ip desconocida @@ -1182,7 +1182,7 @@ %s cancelada Cancelado por usted %s aceptada - Aceptado por usted + Aceptaste Verificacion enviada Solicitud de verificación Verifica esta Sesion @@ -1239,7 +1239,7 @@ Precaucion Error al obtener sesiones Sesiones - Confirmado + Confiable No es confiable Inicializar Firmas Cruzadas Restablecer claves @@ -1255,7 +1255,7 @@ Razón para redactar ${app_name} Android Refrescar - Nuevo inicio de sesión detectado . ¿Fue usted\? + Nuevo inicio de sesión detectado . ¿Has sido tú\? Este no era yo Su cuenta puede estar comprometida Verificación cancelada @@ -1263,7 +1263,7 @@ Clave de mensaje ¡Listo! Cifrado habilitado - Sala creada y configurada por usted. + Creaste y configuraste la sala. Esperando por %s… Ajuste de Notificaciones Mensaje… @@ -1279,7 +1279,7 @@ Si decea resetear su PIN, toque Olvidé PIN para cerrar sesión y restablecer. Numeros telefonicos Correos y numeros telefonicos - Administre el correo y numero telefonico de su cuenta + Administra las direcciones de correo y/o números telefónicos relacionados a tu cuenta de Matrix Mostrar mensajes eliminados Indicar marca de mensaje eliminado ARCHIVOS @@ -1357,7 +1357,7 @@ Hiciste la sala solo por invitación. Únase gratis a millones de personas en el mayor servidor público Continuar con SSO - Dirección de servicios de Element Matrix + Dirección de Element Matrix Services Ingrese la dirección del servidor que desea utilizar Se enviará un correo electrónico de verificación a su bandeja de entrada para confirmar la configuración de su nueva contraseña. Siguiente @@ -1407,7 +1407,7 @@ Advertencia Tu cuenta aún no está creada. ¿Detener el proceso de registro\? Seleccione matrix.org - Seleccionar servicios de matriz de elementos + Seleccionar Element Matrix Services Seleccione un servidor doméstico personalizado Realiza el desafío de captcha Acepta los términos para continuar @@ -1453,7 +1453,7 @@ \nVuelva a iniciar sesión para acceder a los datos y mensajes de su cuenta. Perderás el acceso a los mensajes seguros a menos que inicies sesión para recuperar tus claves de cifrado. La sesión actual es para el usuario %1$s y usted proporciona las credenciales para el usuario %2$s. Esto no está suportado por ${app_name}. -\nPrimero borre los datos, luego inicie sesión nuevamente con otra cuenta. +\nPrimero borra los datos, luego inicia sesión nuevamente con otra cuenta. Su enlace matrix.to estaba mal formado El modo desarrollador activa funciones ocultas y también puede hacer que la aplicación sea menos estable. ¡Solo para desarrolladores! Uno de los siguientes puede verse comprometido: @@ -1462,9 +1462,9 @@ \n- El servidor privado al que está conectado el usuario que estás verificando \n- Su conexión a internet o la de otros usuarios \n- Su dispositivo o el de otros usuarios - Los mensajes de esta sala están cifrados Extremo-a-Extremo. + Los mensajes de esta sala están cifrados de extremo-a-extremo. \n -\nSus mensajes están protegidos y sólo usted y el destinatario tienen las claves únicas para descifrarlos. +\nTus mensajes están protegidos y sólo tu y el destinatario tienen las claves únicas para descifrarlos. Esta sesión no puede compartir esta verificación con sus otras sesiones. \nLa verificación se guardará localmente y se compartirá en una versión futura de la aplicación. Envía el emote dado coloreado como un arcoíris @@ -1474,7 +1474,7 @@ Verifica si los mismos emojis aparecen en el mismo orden en ambos usuarios. Compare el código con el que se muestra en la pantalla del otro usuario. Los mensajes con este usuario están cifrados Extremo-a-Extremo y no pueden ser leídos por terceros. - Su nueva sesión ahora está verificada. Tiene acceso a sus mensajes cifrados y otros usuarios lo verán como de confianza. + Tu nueva sesión acaba de verificarse y ahora tiene acceso a tus mensajes cifrados y otros usuarios la verán como de confianza. La firma cruzada está habilitada \n Claves privadas en el dispositivo. La firma cruzada está habilitada @@ -1484,8 +1484,8 @@ \nLas claves no son de confianza El administrador de su servidor ha desactivado el cifrado Extremo-a-Extremo de forma predeterminada en salas privadas y mensajes directos. No hay información criptográfica disponible - Esta sesión es confiable para mensajería segura porque usted la verificó: - Verifique esta sesión para marcarla como confiable y otorgarle acceso a mensajes cifrados. Si no inició sesión en esta sesión, su cuenta puede verse comprometida: + Esta sesión es confiable para mensajería segura porque la verificaste: + Verifica esta sesión para marcarla como confiable y otorgarle acceso a mensajes cifrados. Si no iniciaste sesión en esta sesión, su cuenta puede haber sido comprometida: %d sesión activa %d sesiones activas @@ -1510,8 +1510,8 @@ Solicitudes clave Desbloquear el historial de mensajes cifrados Utilice esta sesión para verificar su nuevo, otorgándole acceso a mensajes cifrados. - Si cancela, no podrá leer mensajes cifrados en este dispositivo y otros usuarios no confiarán en él - Si cancela, no podrá leer mensajes cifrados en su nuevo dispositivo y otros usuarios no confiarán en él + Si cancelas, no podrás leer mensajes cifrados en este dispositivo y otros usuarios no confiarán en este + Si cancelas, no podrás leer mensajes cifrados en tu nuevo dispositivo y otros usuarios no confiarán en este No verificarás %1$s (%2$s) si cancelas ahora. Comience de nuevo en su perfil de usuario. Uno de los siguientes puede verse comprometido: \n @@ -1524,7 +1524,7 @@ Se canceló la verificación. Puede iniciar la verificación de nuevo. Ingrese su %s para continuar. No use la contraseña de su cuenta. - Ingrese una frase de seguridad que solo usted conozca, que se usa para proteger secretos en su servidor. + Ingresa una frase de seguridad que solo tú conozcas, que se usa para proteger secretos en tu servidor. Esto puede tardar varios segundos, tenga paciencia. Configurando la recuperación. Manténlo seguro @@ -1561,7 +1561,7 @@ Nombre de usuario y / o contraseña incorrectos. La contraseña ingresada comienza o termina con espacios, verifíquela. Esta cuenta ha sido desactivada. Mejora de cifrado disponible - Verifíquese a usted mismo y a los demás para mantener sus chats seguros + Verifícate a ti mismo y a los demás para mantener tus chats seguros No es una clave de recuperación válida Por favor introduce una clave de recuperación Comprobando la clave de respaldo @@ -1622,11 +1622,11 @@ Usa una llave de seguridad Genere una clave de seguridad para almacenar en un lugar seguro, como un administrador de contraseñas o una caja fuerte. Utilice una frase de seguridad - Ingrese una frase secreta que solo usted conozca y genere una clave de respaldo. + Ingresa una frase secreta que solo tú conozcas y genera una clave para tu copia de respaldo. Guarde su llave de seguridad Guarde su llave de seguridad en un lugar seguro, como un administrador de contraseñas o una caja fuerte. Establecer una frase de seguridad - Ingrese una frase de seguridad que solo usted conozca, que se usa para proteger secretos en su servidor. + Ingresa una frase de seguridad que sólo tú conozcas, que se usa para proteger secretos en tu servidor. Frase de seguridad Ingrese su Frase de seguridad nuevamente para confirmarla. Nombre de la Sala @@ -1636,7 +1636,7 @@ Esperando este mensaje, esto puede tardar un poco Debido al cifrado Extremo-a-Extremo, es posible que deba esperar a que llegue el mensaje de alguien porque las claves de cifrado no se le enviaron correctamente. No puede acceder a este mensaje porque ha sido bloqueado por el remitente - No puede acceder a este mensaje porque el remitente no confía en su sesión + No puedes acceder a este mensaje porque el remitente no confía en tu sesión No puede acceder a este mensaje porque el remitente no envió las claves a propósito Esperando al historial de cifrado ¡Nos complace anunciar que hemos cambiado de nombre! Tu aplicación está actualizada y accediste a tu cuenta. @@ -1711,7 +1711,7 @@ Mostrar el dispositivo con el que puede verificar ahora Mostrar %d dispositivos con los que puede verificar ahora - Reiniciará sin historia, mensajes, dispositivos o usuarios verificados + Reiniciarás sin historial, ni mensajes, ni dispositivos o usuarios verificados Si resetea todo Solo haga esto si no tiene otro dispositivo con el que verificar éste. Resetear todo @@ -1748,7 +1748,7 @@ Se necesita una nueva autenticación ¡Código QR no escaneado! Código QR no válido (URL no válida)! - No puede DM usted mismo! + No puedes MD a ti mismo! Compartir por texto Cambiar PIN Cambie su PIN actual @@ -1960,7 +1960,7 @@ Acceso a la sala Siempre preguntar Espacios - mostrar todas las salas en el directorio de salas, incluyendo salas con contenido explícito. + Mostrar todas las salas en el directorio de salas, incluyendo salas con contenido explícito. Mostrar salas con contenido explícito Directorio de la sala Salas sugeridas @@ -2181,7 +2181,7 @@ Agregar nuevas palabra clave Tus palabras clave Habilitar notificación por correo electrónico para %s - Para recibir un correo electrónico con una notificación, asocie un correo electrónico a su cuenta de matrix + Para recibir notificaciones por correo electrónico, asocia una direccion de correo electrónico a tu cuenta de Matrix Notificación de correo electrónico Ninguno Solo menciones y palabras clave @@ -2219,7 +2219,7 @@ No se puede grabar un mensaje de voz No se puede reproducir este mensaje de voz Toca tu grabación para detenerla o escucharla - %1$ds dejado + Restan %1$ds Mantenga presionado para grabar, suelte para enviar Eliminar grabación Grabación de mensaje de voz @@ -2238,7 +2238,7 @@ ¡Se ha cerrado la sesión! ¡Se ha abandonado la sala! Consejo: Pulse prolongadamente un mensaje y use \"%s\" . - Mantén las conversaciones organizadas con hilos + Mantén las conversaciones organizadas usando hilos Muestra todos los hilos en que has participado Mis Hilos Muestra todos los hilos de la sala actual @@ -2457,7 +2457,7 @@ BETA Comentarios de la beta de hilos Beta de hilos - - Algunos usuarios han sido dejados de ignorar + - Algunos usuarios han dejado de ser ignorados La compartición de pantalla está en progreso ${app_name} Compartición de pantalla Dejar de compartir pantalla @@ -2474,7 +2474,7 @@ Actualizado hace %1$s Implementación temporal: las ubicaciones persisten en el historial de la sala Activar compartir ubicación en tiempo real - Queda %1$s + Restan %1$s Compartiendo hasta %1$s Ver ubicación en tiempo real La ubicación en tiempo real ha terminado @@ -2625,8 +2625,8 @@ \nPor favor, inténtelo de nuevo.%s Usar ajustes por defecto del sistema Escoger manualmente - Tamaño automático de fuente - Escoger tamaño de la fuente + Tamaño automático + Escoge tamaño del tipo de letra %1$s y %2$d otro %1$s y %2$d otros @@ -2659,18 +2659,33 @@ Otorgar permiso ${app_name} necesita permiso para mostrar notificaciones. \nPor favor, otórgalo. - ${app_name} necesita permisos para mostrar notificaciones. Las notificaciones pueden mostrar tus mensajes, invitaciones, etc. + ${app_name} necesita permiso para mostrar notificaciones. Las notificaciones pueden mostrar tus mensajes, invitaciones, etc. \n -\nPor favor, permite el acceso en las siguientes ventanas emergentes para poder visualizar notificaciones. - Prueba el editor de texto enriquecido (pronto llegará la opción de texto sin formato plain text) +\nPor favor, a continuacion, en las ventanas emergentes, permite el acceso para poder visualizar notificaciones. + Prueba el editor de texto enriquecido (pronto llegará la opción de texto simple, sin formato) Habilitar editor de texto enriquecido (rich text) Crear MD únicamente al primer mensaje Una versión simplificada de Element con pestañas opcionales Habilitar nueva disposición - Sí, Parar + Sí, Detener Deseleccionar todo - Ocultar los hijos de %s - Mostrar los hijos de %s + Ocultar los subespacios de %s + Mostrar los subespacios de %s Has finalizado una transmisión de voz. %1$s ha finalizado una transmisión de voz. + Element Matrix Services (EMS) es un servicio de alojamiento para tus comunicaciones en tiempo real. Robusto, confiable, rápido y seguro. Para saber cómo, ve a <a href=\"${ftue_ems_url}\">element.io/ems</a> + Difusión de voz + Habilitado: + ID de sesión: + Algo falló. Por favor, comprueba tu conexión de red e inténtalo nuevamente. + Citando + Respondiendo a %s + Editando + Abrir pantalla de herramientas de desarrollador + 🔒 Tienes habilitado el cifrado a sesiones verificadas sólo para todas las salas en Ajustes de Seguridad. + ⚠ Hay dispositivos sin verificar en esta sala, los cuales no seran capaces de descifrar los mensajes que envías. + Habilita MDs pospuestos + Mostrar chats recientes en el menú de compartir sistema + No enviar nunca mensajes cifrados a sesiones sin verificar en esta sala. + Restan %1$s \ No newline at end of file From f790921785b91b1d46fa5a48199047abf9420ac5 Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues Costa Date: Wed, 4 Jan 2023 21:12:32 +0000 Subject: [PATCH 233/246] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2576 of 2576 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 | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 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 bc617c62f0..a5aa778156 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 @@ -5,24 +5,24 @@ %1$s convidou você %1$s entrou na sala %1$s saiu da sala - %1$s rejeitou o convite + %1$s recusou o convite %1$s removeu %2$s %1$s desbaniu %2$s %1$s baniu %2$s - %1$s retirou o convite de %2$s - %1$s mudou o avatar dela(e) - %1$s definiu o nome de exibição dela(e) para %2$s - %1$s mudou o nome de exibição dela(e) de %2$s para %3$s - %1$s removeu o nome de exibição dela(e) (era %2$s) + %1$s desfez o convite para %2$s + %1$s mudou seu avatar + %1$s definiu seu nome de exibição para %2$s + %1$s mudou seu nome de exibição de %2$s para %3$s + %1$s removeu seu nome de exibição (era %2$s) %1$s mudou o tópico para: %2$s %1$s mudou o nome da sala para: %2$s %s começou uma chamada de vídeo. %s começou uma chamada de voz. %s atendeu a chamada. - %s terminou a chamada. - %1$s fez histórico futuro da sala visível para %2$s - todos os membros da sala, do ponto que foram convidados. - todos os membros da sala, do ponto que se juntaram. + %s encerrou a chamada. + %1$s tornou o histórico futuro da sala visível para %2$s + todos os membros da sala, a partir do ponto que foram convidados. + todos os membros da sala, a partir do ponto que entraram. todos os membros da sala. qualquer pessoa. (avatar mudou também) @@ -45,11 +45,11 @@ Você convidou %1$s Você entrou na sala Você saiu da sala - Você rejeitou o convite + Você recusou o convite Você removeu %1$s Você desbaniu %1$s Você baniu %1$s - Você retirou o convite de %1$s + Você desfez o convite para %1$s Você mudou seu avatar Você definiu seu nome de exibição para %1$s Você mudou seu nome de exibição de %1$s para %2$s @@ -63,8 +63,8 @@ %s enviou dados para configurar a chamada. Você enviou dados para configurar a chamada. Você atendeu a chamada. - Você terminou a chamada. - Você fez histórico futuro da sala visível para %1$s + Você encerrou a chamada. + Você tornou o histórico futuro da sala visível para %1$s %s fez o upgrade desta sala. Você fez o upgrade desta sala. Você removeu o nome da sala @@ -170,8 +170,8 @@ %1$s convidou %2$s Você fez o upgrade aqui. %s fez o upgrade aqui. - Você fez mensagens futuras visíveis para %1$s - %1$s fez mensagens futuras visíveis para %2$s + Você tornou as mensagens futuras visíveis para %1$s + %1$s tornou as mensagens futuras visíveis para %2$s Você saiu da sala %1$s saiu da sala Você entrou @@ -408,7 +408,7 @@ Qualquer pessoa Membros somente (desde o ponto no tempo de seleção desta opção) Membros somente (desde que eles foram convidados) - Membros somente (desde que eles se juntaram) + Membros somente (desde que eles entraram) Usuárias(os) banidas(os) Avançadas ID interno desta sala @@ -2009,8 +2009,8 @@ Adicionar salas Explorar salas - %d pessoa que você conhece já tem se juntado - %d pessoas que você conhece já têm se juntado + %d pessoa que você conhece já entrou + %d pessoas que você conhece já entraram Juntar-Se a Espaço Criar espaço @@ -2833,8 +2833,8 @@ Desselecionar todas(os) Selecionar todas(os) - %1$d selecionada(o) - %1$d selecionadas(os) + %1$d selecionado(a) + %1$d selecionados(as) Alguma outra pessoa já está gravando um broadcast de voz. Espere que o broadcast de voz dela termine para começar um novo. Alternar modo de tela cheia From ed84212c78d176c06760c9be65a097d11781e7ed Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 4 Jan 2023 17:01:03 +0000 Subject: [PATCH 234/246] Translated using Weblate (Albanian) Currently translated at 99.3% (2558 of 2576 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- library/ui-strings/src/main/res/values-sq/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ui-strings/src/main/res/values-sq/strings.xml b/library/ui-strings/src/main/res/values-sq/strings.xml index 3b233c087c..b170d306e4 100644 --- a/library/ui-strings/src/main/res/values-sq/strings.xml +++ b/library/ui-strings/src/main/res/values-sq/strings.xml @@ -2504,7 +2504,7 @@ %s \nduket paksa si i zbrazët. Jini në gjendje të incizoni dhe dërgoni transmetim zanor në rrjedhën kohore të dhomës. - Aktivizoni transmetim zanor + Aktivizoni transmetim zanor (nën zhvillim aktiv) Aktivizo regjistrim hollësish klienti Shihini më qartë dhe kontrolloni më mirë krejt sesionet tuaj. Aktivizo përgjegjës të ri sesionesh From 860df019025ac652ef265814afa8eec759ce099d Mon Sep 17 00:00:00 2001 From: Vri Date: Wed, 4 Jan 2023 16:20:15 +0000 Subject: [PATCH 235/246] Translated using Weblate (German) Currently translated at 100.0% (89 of 89 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/40105160.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40105180.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40105160.txt b/fastlane/metadata/android/de-DE/changelogs/40105160.txt new file mode 100644 index 0000000000..c55d8d998f --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Threads sind nun standardmäßig aktiviert. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/de-DE/changelogs/40105180.txt b/fastlane/metadata/android/de-DE/changelogs/40105180.txt new file mode 100644 index 0000000000..c55d8d998f --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Die wichtigsten Änderungen in dieser Version: Threads sind nun standardmäßig aktiviert. +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases From bd21f032d4a53d0292f4c580c237cf573ba74361 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 5 Jan 2023 08:42:07 +0000 Subject: [PATCH 236/246] Translated using Weblate (French) Currently translated at 100.0% (89 of 89 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/40105160.txt | 2 ++ fastlane/metadata/android/fr-FR/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40105180.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105160.txt b/fastlane/metadata/android/fr-FR/changelogs/40105160.txt new file mode 100644 index 0000000000..4101bb0c86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Fils de discussion activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40105180.txt b/fastlane/metadata/android/fr-FR/changelogs/40105180.txt new file mode 100644 index 0000000000..4101bb0c86 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Fils de discussion activés par défaut. +Intégralité des changements : https://github.com/vector-im/element-android/releases From 271b828be09c638cbc43a30708be8404493ac255 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 4 Jan 2023 18:55:35 +0000 Subject: [PATCH 237/246] Translated using Weblate (Hungarian) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/hu/ --- fastlane/metadata/android/hu-HU/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40105180.txt diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105160.txt b/fastlane/metadata/android/hu-HU/changelogs/40105160.txt new file mode 100644 index 0000000000..c5dc38bc8f --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Új üzenetszálak alapból bekapcsolva! +Teljes változási napló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40105180.txt b/fastlane/metadata/android/hu-HU/changelogs/40105180.txt new file mode 100644 index 0000000000..cc70967e58 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Legnagyobb változtatás ebben a verzióban: Az üzenetszálak alapból bekapcsolva! +Teljes változási napló: https://github.com/vector-im/element-android/releases From 96363fb789f82acbb24d1bb55f1c3bad505431c5 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Wed, 4 Jan 2023 16:18:18 +0000 Subject: [PATCH 238/246] Translated using Weblate (Slovak) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/sk/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40105180.txt diff --git a/fastlane/metadata/android/sk/changelogs/40105160.txt b/fastlane/metadata/android/sk/changelogs/40105160.txt new file mode 100644 index 0000000000..d5b5ad330d --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna sú teraz predvolene zapnuté. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sk/changelogs/40105180.txt b/fastlane/metadata/android/sk/changelogs/40105180.txt new file mode 100644 index 0000000000..d5b5ad330d --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna sú teraz predvolene zapnuté. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases From 2903a644f2e258f6509e7dfa126bca5bcfed9c37 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Wed, 4 Jan 2023 19:24:53 +0000 Subject: [PATCH 239/246] Translated using Weblate (Ukrainian) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/uk/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/uk/changelogs/40105180.txt diff --git a/fastlane/metadata/android/uk/changelogs/40105160.txt b/fastlane/metadata/android/uk/changelogs/40105160.txt new file mode 100644 index 0000000000..edbd209d17 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Гілки відтепер типово ввімкнено. +Перелік усіх змін: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/uk/changelogs/40105180.txt b/fastlane/metadata/android/uk/changelogs/40105180.txt new file mode 100644 index 0000000000..edbd209d17 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Гілки відтепер типово ввімкнено. +Перелік усіх змін: https://github.com/vector-im/element-android/releases From 8a5aad1ba0a3ee66e40b10f05fafa22641cf63dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 5 Jan 2023 07:22:25 +0000 Subject: [PATCH 240/246] Translated using Weblate (Estonian) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/et/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/et/changelogs/40105180.txt diff --git a/fastlane/metadata/android/et/changelogs/40105160.txt b/fastlane/metadata/android/et/changelogs/40105160.txt new file mode 100644 index 0000000000..9aadf5dae8 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on vaikimisi kasutusel. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/et/changelogs/40105180.txt b/fastlane/metadata/android/et/changelogs/40105180.txt new file mode 100644 index 0000000000..9aadf5dae8 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on vaikimisi kasutusel. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases From ff9cf8fd2f0e3edcfb0d55bddf86dad31938cdb3 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Wed, 4 Jan 2023 17:43:34 +0000 Subject: [PATCH 241/246] Translated using Weblate (Persian) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/fa/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/fa/changelogs/40105180.txt diff --git a/fastlane/metadata/android/fa/changelogs/40105160.txt b/fastlane/metadata/android/fa/changelogs/40105160.txt new file mode 100644 index 0000000000..0c3cc5aa31 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105160.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رشته‌ها اکنون به صورت پیش‌گزیده به کار افتاده‌اند. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fa/changelogs/40105180.txt b/fastlane/metadata/android/fa/changelogs/40105180.txt new file mode 100644 index 0000000000..0c3cc5aa31 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40105180.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: رشته‌ها اکنون به صورت پیش‌گزیده به کار افتاده‌اند. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases From 53db9885252338dd8aecc7ce88f1832ff00401fd Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Thu, 5 Jan 2023 16:06:48 +0000 Subject: [PATCH 242/246] Translated using Weblate (Esperanto) Currently translated at 2.2% (2 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/eo/ --- fastlane/metadata/android/eo/short_description.txt | 2 +- fastlane/metadata/android/eo/title.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/metadata/android/eo/short_description.txt b/fastlane/metadata/android/eo/short_description.txt index 33013ce78f..05a4aaf191 100644 --- a/fastlane/metadata/android/eo/short_description.txt +++ b/fastlane/metadata/android/eo/short_description.txt @@ -1 +1 @@ -Sekura kaj sencentrigita vokado kaj babilado. Tenu viajn datumojn sekuraj. +Grupa mesaĝisto - ĉifrita mesaĝado, grupa babilejo kaj videovokoj diff --git a/fastlane/metadata/android/eo/title.txt b/fastlane/metadata/android/eo/title.txt index f56927e529..85b92c693b 100644 --- a/fastlane/metadata/android/eo/title.txt +++ b/fastlane/metadata/android/eo/title.txt @@ -1 +1 @@ -Element (antaŭe Riot.im) +Element - Sekura Tujmesaĝilo From 0882e1bf81b17f4afb84cb2dcf11c4bae38d44c9 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 5 Jan 2023 02:10:13 +0000 Subject: [PATCH 243/246] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (89 of 89 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/40105160.txt | 2 ++ fastlane/metadata/android/zh-TW/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40105180.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105160.txt b/fastlane/metadata/android/zh-TW/changelogs/40105160.txt new file mode 100644 index 0000000000..9c66f3c2ad --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105160.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串現在預設啟用。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/zh-TW/changelogs/40105180.txt b/fastlane/metadata/android/zh-TW/changelogs/40105180.txt new file mode 100644 index 0000000000..9c66f3c2ad --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40105180.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串現在預設啟用。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases From 5734a270d8b1630f43543747174336191fe2bdb5 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 4 Jan 2023 16:04:26 +0000 Subject: [PATCH 244/246] Translated using Weblate (Czech) Currently translated at 100.0% (89 of 89 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/40105160.txt | 2 ++ fastlane/metadata/android/cs-CZ/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40105180.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105160.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105160.txt new file mode 100644 index 0000000000..69c2b3304c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení. +Úplný seznam změn: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40105180.txt b/fastlane/metadata/android/cs-CZ/changelogs/40105180.txt new file mode 100644 index 0000000000..69c2b3304c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Vlákna jsou nyní povolena ve výchozím nastavení. +Úplný seznam změn: https://github.com/vector-im/element-android/releases From 4f2550ae923b1be83c41c501a2283f37d3bfe4f7 Mon Sep 17 00:00:00 2001 From: Linerly Date: Wed, 4 Jan 2023 22:47:24 +0000 Subject: [PATCH 245/246] Translated using Weblate (Indonesian) Currently translated at 100.0% (89 of 89 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40105160.txt | 2 ++ fastlane/metadata/android/id/changelogs/40105180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40105160.txt create mode 100644 fastlane/metadata/android/id/changelogs/40105180.txt diff --git a/fastlane/metadata/android/id/changelogs/40105160.txt b/fastlane/metadata/android/id/changelogs/40105160.txt new file mode 100644 index 0000000000..173a1bfb1b --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105160.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Utasan sekarang diaktifkan secara bawaan. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/id/changelogs/40105180.txt b/fastlane/metadata/android/id/changelogs/40105180.txt new file mode 100644 index 0000000000..173a1bfb1b --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40105180.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Utasan sekarang diaktifkan secara bawaan. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases From e9d1de8fbac8d93f6a98aa3cc706f6ad16ea8f10 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 6 Jan 2023 17:36:40 +0100 Subject: [PATCH 246/246] Fix compilation issue after rebase. --- .../core/platform/VectorBaseDialogFragment.kt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseDialogFragment.kt index 5a817b989e..34e233aa7a 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseDialogFragment.kt @@ -23,8 +23,10 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.CallSuper import androidx.fragment.app.DialogFragment +import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView import dagger.hilt.android.EntryPointAccessors @@ -37,6 +39,7 @@ import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.themes.ThemeUtils import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import reactivecircus.flowbinding.android.view.clicks import timber.log.Timber @@ -145,11 +148,15 @@ abstract class VectorBaseDialogFragment : DialogFragment(), Ma * ========================================================================================== */ protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { - viewEvents - .stream() - .onEach { - observer(it) - } - .launchIn(viewLifecycleOwner.lifecycleScope) + val tag = this@VectorBaseDialogFragment::class.simpleName.toString() + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewEvents + .stream(tag) + .collect { + observer(it) + } + } + } } }