mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-01 13:46:57 +02:00
7b47015685
* spacing improved further * Use unstable prefixes for QR code login * Changelog * Force update client information * Changelog * Fix incorrect Task creation for processing scanned qr codes * Check and mark the received MSK as trusted before locally verifying the existing device * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6909) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6910) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6909) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6911) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6909) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6910) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6909) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Translations update from Weblate (#6908) * Translated using Weblate (Bulgarian) Currently translated at 100.0% (8 of 8 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/bg/ * Translations update from Weblate (#6907) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> * Translations update from Weblate (#6915) * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.2% (1870 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Bulgarian) Currently translated at 66.4% (1529 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/bg/ * Translated using Weblate (Italian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 97.5% (2245 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2301 of 2301 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> * Missing change from fix * changelog * Only running alpha builds when PR labeled with `Trigger-PR-Build` * Configure codecov flags and have them be carried forward * Add pull request change types for triggering alpha builds * Updated templates readme.md file * Add private var for avatar menu * Cleanup createAvatarButtonItem method * Add multiple fallbacks in AvatarViewDataProtocol * Changelog * Prepare for new sprint * Add changelog.d file * Remove space * Init voice broadcast playing service * Add some comments * Add chunks in TimelineVoiceBroadcastDetails * Check user id to prevent fake ckunk * Rename TimelineVoiceBroadcastCoordinator to controller It has nothing todo with a coordinator. Start to follow the same naming as VoiceMessage. Remove SwiftUI VoiceBroadcastChunk to make it build * Removed VoiceBroadcastProtocol We do not need to abstract it * Simplify TimelineVoiceBroadcastDetails struct * Rename some existing voice broadcast files to VoiceBroadcastPlayback Record will happen in separate files * Renamed back to VoiceBroadcastPlaybackCoordinator The logic will be moved to the view model. This file will just serve the SwiftUI view * Fix text view height issue * Add changelog.d file * Aggregate chunks in voice broacast * VB: Move view logic to the view model * Add device_id and record tag * VB: Playback starts to work but only the first chunk if it is ogg * Translated using Weblate (Hungarian) Currently translated at 100.0% (2302 of 2302 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * updated the package * Remove clips to bounds for text views inside bubbles * Improve http url interaction ux * Edit mode * Add changelog.d file * VB: Improve playback states * added placeholder to the viewModel * Expose better broadcast details to the view Starting from the sender name but we can add more things. This is up to the design expectation * Session selection state * Update the Voice Broadcast Labs flag description * Device-to-device verification * rich text composer placeholder text implemented using the same logic of the normal composer * Support mp4 audio file format * added a simple test * improving code * VB: Make the view model aware of every chunk new coming this reactive approach will help to cache and reorder them by sequence * fixing a legacy issue that sometime removed the placeholder * improved old code * improved old code further * - Fix the RoomBubbleCellData tag management (Record/Playback/NoDisplay) - Force the VB display even if the Labs flag is disabled. The Labs flag is only used now to block VB recording and sending - Fix: Release VBService when the user stops the broadcast * VoiceMessageAudioPlayer: Add support of URLs queue playback To be used for voice broadcast * VB: Support multi chunks playback * Display info dialogs when we prevent the user from starting a new voice broadcast - Update the existing implementation used to start/stop a voice broadcast in order to handle the different cases where voice broadcast is denied - Add the optional Voice broadcast action to the new wysiwyg composer * Init voice broadcast playing service * Add some comments * Add chunks in TimelineVoiceBroadcastDetails * Check user id to prevent fake ckunk * Rename TimelineVoiceBroadcastCoordinator to controller It has nothing todo with a coordinator. Start to follow the same naming as VoiceMessage. Remove SwiftUI VoiceBroadcastChunk to make it build * Removed VoiceBroadcastProtocol We do not need to abstract it * Simplify TimelineVoiceBroadcastDetails struct * Rename some existing voice broadcast files to VoiceBroadcastPlayback Record will happen in separate files * Renamed back to VoiceBroadcastPlaybackCoordinator The logic will be moved to the view model. This file will just serve the SwiftUI view * Aggregate chunks in voice broacast * VB: Move view logic to the view model * Add device_id and record tag * VB: Playback starts to work but only the first chunk if it is ogg * VB: Improve playback states * Expose better broadcast details to the view Starting from the sender name but we can add more things. This is up to the design expectation * Update the Voice Broadcast Labs flag description * Support mp4 audio file format * VB: Make the view model aware of every chunk new coming this reactive approach will help to cache and reorder them by sequence * VoiceMessageAudioPlayer: Add support of URLs queue playback To be used for voice broadcast * VB: Support multi chunks playback * - Fix the RoomBubbleCellData tag management (Record/Playback/NoDisplay) - Force the VB display even if the Labs flag is disabled. The Labs flag is only used now to block VB recording and sending - Fix: Release VBService when the user stops the broadcast * Fixes after rebase on develop Update voice broadcast playback UI * Add voice broadcast error view * Remove matrixsdk import * VB: Manage playback completion properly Make VoiceManager audioPlayerDidFinishPlaying called when the last item of the playlist has been played * VB: Introduce VoiceBroadcastState for the UI * Add issue automation for PS features teams * Update issue automation for design Put only high priority issues in front of the design team, all of which the design team will aim to action to keep the queue at zero * Clarify issue automation conditions Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> * Removed sections * VB: Started live playback * VB: Support live playback from the beginning or with go live * VB: Own code review * UI fixes * Fix infinite layout loops on timeline (#6942) * Remove `forceZeroSageAreaInsets` from `VectorHostingController` * Fix layout issues when adding hosting views into the content view * Use the new api when adding views into the content * Add changelog * VB: Remove a done TODO * Display live voice broadcast * Fix crash * VB: Fix playLive after pause * Fixes after rebase from develop * VB: Hack to make the project build for SwiftUI tests We need to rework the view model to remove its dependency on MatrixSDK * Update UI * VB: Moved the VM temporary under a MatrixSDK to avoid to use it on the SwiftUI build * the voice message toolbar now appears * First part of the voice broadcast recording feature * Fix missing parts on Voice broadcast recorder service * Update recorder view and content * Add sequence value when sending chunk files * Update recorder service * Fix recorder service for audio node after stopping a record * Fix UI status at record startup and depending on the recording status * Send the last chunk file after stopping or pausing a record * Update recording state after stopping voice broadcast on every cases * BF Ignore redacted voice broadcast state event (their content is empty) * Update first chunk number * Remove temporary code for stopping recording * Update sequence number associated to chunk file sending * Add AAC to M4A converter and now convert chunks before sending them * Remove useless log in VoiceBroadcastRecorderService * Fix a potential crash when trying to send a nil chunk file (in case of stop immediately after pause) * Set voice broadcast recording to pause when the app goes in background and when the RVC will disappear * Enhance RoomBubbleCellData handling - detect correctly an actual live recording - update the tile display at the end of a live recording * Add missing update state after switching to resumed state * Fix API change for VectorHostingController * Update record UI to be in sync with other platforms * Remove useless imports * voice messages implemented * fix * Clean code * Enhance chunk sending mecanism in recorder service * voice message support added to the rich text composer * Select All * fix for tests * new pushed mic asset * Unit tests * should fix the CI UI tests failing * Changelog * reimplemented but the animation and the spacing needs some fixing * fixing view not returning in place * animation * More UI tests * improving anim, however it only works with swiftui build * Code review fixes * minor adjustments * Stop running UI tests on pushes to develop, they already run on PRs * Fixes #6879 - Xcode 14 resource bundle signing errors * Translated using Weblate (German) Currently translated at 100.0% (2307 of 2307 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Persian) Currently translated at 45.1% (1042 of 2307 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/fa/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2307 of 2307 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (German) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Russian) Currently translated at 81.0% (1870 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2308 of 2308 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Polish) Currently translated at 94.1% (2175 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pl/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Define MXCrypto and MXCrossSigning as protocols * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * speeding the animation a bit * tests and identifier improvements * fix * changelog * removed unused code * comment * Curate MXCrypto protocol methods * Complete MXCryptoV2 implementation * Switch the CI to code 14 and the iOS 14 simulator, fix UI tests * Fixes #6987 - Prevent ZXing from unnecessarily requesting camera access * Fixes #6988 - Prevent actor switching when tearing down the rendezvous * add Z-Labs tag or rich text editor and update to the new label naming * changelog * Hide old sessions list when the new dm is enabled * Add changelog.d file * CryptoV2 changes * Display crypto version * Add issue automation for the VoIP team * Fix typo in issue automation * Translations update from Weblate (#7017) * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Dutch) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johan Smits <johan@smitsmail.net> * changelog.d: Upgrade MatrixSDK version ([v0.24.2](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.24.2)). * version++ Co-authored-by: Mauro Romito <mauro.romito@element.io> Co-authored-by: Alfonso Grillo <alfogrillo@element.io> Co-authored-by: David Langley <langley.dave@gmail.com> Co-authored-by: Velin92 <34335419+Velin92@users.noreply.github.com> Co-authored-by: Hugh Nimmo-Smith <hughns@element.io> Co-authored-by: Aleksandrs Proskurins <paleksandrs@gmail.com> Co-authored-by: Aleksandrs Proskurins <aleksandrsp@element.io> Co-authored-by: Stefan Ceriu <stefanc@matrix.org> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org> Co-authored-by: Nui Harime <harime.nui@yandex.ru> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Slavi Pantaleev <slavi@devture.com> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: Weblate <noreply@weblate.org> Co-authored-by: Element Translate Bot <admin@riot.im> Co-authored-by: Alfonso Grillo <alfogrillo@gmail.com> Co-authored-by: yostyle <y.pintas@gmail.com> Co-authored-by: manuroe <manu@matrix.org> Co-authored-by: Giom Foret <giom@matrix.org> Co-authored-by: Andy Uhnak <andyuhnak@gmail.com> Co-authored-by: giomfo <gforet@matrix.org> Co-authored-by: Kat Gerasimova <ekaterinag@element.io> Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> Co-authored-by: Doug <douglase@element.io> Co-authored-by: Philippe Loriaux <philippel@element.io> Co-authored-by: manuroe <manuroe@users.noreply.github.com> Co-authored-by: mmehdishafiee <mmhdishafiee@gmail.com> Co-authored-by: Bartosz <barpaw@gmail.com> Co-authored-by: Johan Smits <johan@smitsmail.net> Co-authored-by: gulekismail <ismailgulek0@gmail.com>
814 lines
36 KiB
Swift
814 lines
36 KiB
Swift
// File created from ScreenTemplate
|
|
// $ createScreen.sh Onboarding Authentication
|
|
/*
|
|
Copyright 2021 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.
|
|
*/
|
|
|
|
import UIKit
|
|
import CommonKit
|
|
|
|
struct AuthenticationCoordinatorParameters {
|
|
let navigationRouter: NavigationRouterType
|
|
/// The screen that should be shown when starting the flow.
|
|
let initialScreen: AuthenticationCoordinator.EntryPoint
|
|
/// Whether or not the coordinator should show the loading spinner, key verification etc.
|
|
let canPresentAdditionalScreens: Bool
|
|
}
|
|
|
|
/// A coordinator that handles authentication, verification and setting a PIN.
|
|
final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtocol {
|
|
|
|
enum EntryPoint {
|
|
case registration
|
|
case login
|
|
}
|
|
|
|
// MARK: - Properties
|
|
|
|
// MARK: Private
|
|
|
|
private let navigationRouter: NavigationRouterType
|
|
private let authenticationService = AuthenticationService.shared
|
|
|
|
/// The initial screen to be shown when starting the coordinator.
|
|
private let initialScreen: EntryPoint
|
|
/// The type of authentication that was used to complete the flow.
|
|
private var authenticationType: AuthenticationType?
|
|
|
|
/// The presenter used to handler authentication via SSO.
|
|
private var ssoAuthenticationPresenter: SSOAuthenticationPresenter?
|
|
/// The transaction ID used when presenting the SSO screen. Used when completing via a deep link.
|
|
private var ssoTransactionID: String?
|
|
|
|
/// Whether the coordinator can present further screens after a successful login has occurred.
|
|
private var canPresentAdditionalScreens: Bool
|
|
/// `true` if presentation of the verification screen is blocked by `canPresentAdditionalScreens`.
|
|
private var isWaitingToPresentCompleteSecurity = false
|
|
|
|
/// The listener object that informs the coordinator whether verification needs to be presented or not.
|
|
private var verificationListener: SessionVerificationListener?
|
|
|
|
private var indicatorPresenter: UserIndicatorTypePresenterProtocol
|
|
private var successIndicator: UserIndicator?
|
|
|
|
/// The password entered, for use when setting up cross-signing.
|
|
private var password: String?
|
|
/// The session created when successfully authenticated.
|
|
private var session: MXSession?
|
|
|
|
// MARK: Public
|
|
|
|
// Must be used only internally
|
|
var childCoordinators: [Coordinator] = []
|
|
var callback: ((AuthenticationCoordinatorResult) -> Void)?
|
|
|
|
// MARK: - Setup
|
|
|
|
init(parameters: AuthenticationCoordinatorParameters) {
|
|
self.navigationRouter = parameters.navigationRouter
|
|
self.initialScreen = parameters.initialScreen
|
|
self.canPresentAdditionalScreens = parameters.canPresentAdditionalScreens
|
|
|
|
indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: parameters.navigationRouter.toPresentable())
|
|
|
|
super.init()
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
func start() {
|
|
Task { @MainActor in
|
|
await startAuthenticationFlow()
|
|
callback?(.didStart)
|
|
authenticationService.delegate = self
|
|
}
|
|
}
|
|
|
|
func toPresentable() -> UIViewController {
|
|
navigationRouter.toPresentable()
|
|
}
|
|
|
|
func presentPendingScreensIfNecessary() {
|
|
canPresentAdditionalScreens = true
|
|
|
|
showLoadingAnimation()
|
|
|
|
if isWaitingToPresentCompleteSecurity {
|
|
isWaitingToPresentCompleteSecurity = false
|
|
presentCompleteSecurity()
|
|
}
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
/// Starts the authentication flow.
|
|
@MainActor private func startAuthenticationFlow() async {
|
|
if let softLogoutCredentials = authenticationService.softLogoutCredentials,
|
|
let homeserverAddress = softLogoutCredentials.homeServer {
|
|
do {
|
|
try await authenticationService.startFlow(.login, for: homeserverAddress)
|
|
} catch {
|
|
MXLog.error("[AuthenticationCoordinator] start: Failed to start")
|
|
displayError(message: error.localizedDescription)
|
|
}
|
|
|
|
await showSoftLogoutScreen(softLogoutCredentials)
|
|
|
|
return
|
|
}
|
|
|
|
let flow: AuthenticationFlow = initialScreen == .login ? .login : .register
|
|
do {
|
|
// Start the flow using the default server (or a provisioning link if set).
|
|
try await authenticationService.startFlow(flow)
|
|
} catch {
|
|
MXLog.error("[AuthenticationCoordinator] start: Failed to start, showing server selection.")
|
|
showServerSelectionScreen(for: flow)
|
|
return
|
|
}
|
|
|
|
switch initialScreen {
|
|
case .registration:
|
|
if authenticationService.state.homeserver.needsRegistrationFallback {
|
|
showFallback(for: flow)
|
|
} else {
|
|
showRegistrationScreen()
|
|
}
|
|
case .login:
|
|
if authenticationService.state.homeserver.needsLoginFallback {
|
|
showFallback(for: flow)
|
|
} else {
|
|
showLoginScreen()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Pushes the server selection screen into the flow (other screens may also present it modally later).
|
|
@MainActor private func showServerSelectionScreen(for flow: AuthenticationFlow) {
|
|
MXLog.debug("[AuthenticationCoordinator] showServerSelectionScreen")
|
|
let parameters = AuthenticationServerSelectionCoordinatorParameters(authenticationService: authenticationService,
|
|
flow: flow,
|
|
hasModalPresentation: false)
|
|
let coordinator = AuthenticationServerSelectionCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self, weak coordinator] result in
|
|
guard let self = self, let coordinator = coordinator else { return }
|
|
self.serverSelectionCoordinator(coordinator, didCompleteWith: result, for: flow)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.push(coordinator, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
|
|
/// Shows the next screen in the flow after the server selection screen.
|
|
@MainActor private func serverSelectionCoordinator(_ coordinator: AuthenticationServerSelectionCoordinator,
|
|
didCompleteWith result: AuthenticationServerSelectionCoordinatorResult,
|
|
for flow: AuthenticationFlow) {
|
|
switch result {
|
|
case .updated:
|
|
if flow == .register {
|
|
showRegistrationScreen()
|
|
} else {
|
|
showLoginScreen()
|
|
}
|
|
case .dismiss:
|
|
MXLog.failure("[AuthenticationCoordinator] AuthenticationServerSelectionScreen is requesting dismiss when part of a stack.")
|
|
}
|
|
}
|
|
|
|
/// Presents an alert on top of the navigation router with the supplied error message.
|
|
@MainActor private func displayError(message: String) {
|
|
let alert = UIAlertController(title: VectorL10n.error, message: message, preferredStyle: .alert)
|
|
alert.addAction(UIAlertAction(title: VectorL10n.ok, style: .default))
|
|
toPresentable().present(alert, animated: true)
|
|
}
|
|
|
|
/// Prompts the user to confirm that they would like to cancel the registration flow.
|
|
@MainActor private func displayCancelConfirmation() {
|
|
let alert = UIAlertController(title: VectorL10n.warning,
|
|
message: VectorL10n.authenticationCancelFlowConfirmationMessage,
|
|
preferredStyle: .alert)
|
|
|
|
alert.addAction(UIAlertAction(title: VectorL10n.no, style: .cancel))
|
|
alert.addAction(UIAlertAction(title: VectorL10n.yes, style: .default) { [weak self] _ in
|
|
self?.cancelRegistration()
|
|
})
|
|
|
|
toPresentable().present(alert, animated: true)
|
|
}
|
|
|
|
/// Prompts the user to trust a certificate by displaying its fingerprint (SHA256).
|
|
@MainActor private func displayUnrecognizedCertificateAlert(for certificate: Data) async -> Bool {
|
|
await withCheckedContinuation { continuation in
|
|
let title = VectorL10n.sslCouldNotVerify
|
|
let homeserverURLString = VectorL10n.sslHomeserverUrl(authenticationService.state.homeserver.displayableAddress)
|
|
let fingerprint = VectorL10n.sslFingerprintHash("SHA256")
|
|
let certificateFingerprint = (certificate as NSData).mx_SHA256AsHexString() ?? VectorL10n.error
|
|
|
|
let message = [VectorL10n.sslCertNotTrust,
|
|
VectorL10n.sslCertNewAccountExpl,
|
|
homeserverURLString,
|
|
fingerprint,
|
|
certificateFingerprint,
|
|
VectorL10n.sslOnlyAccept]
|
|
.joined(separator: "\n\n")
|
|
|
|
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
|
|
|
alert.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel) { action in
|
|
continuation.resume(with: .success(false))
|
|
})
|
|
|
|
alert.addAction(UIAlertAction(title: VectorL10n.sslTrust, style: .default) { action in
|
|
continuation.resume(with: .success(true))
|
|
})
|
|
|
|
// The alert will be encountered on the current stack or when server selection is being presented.
|
|
let presentingViewController = toPresentable().presentedViewController ?? toPresentable()
|
|
presentingViewController.present(alert, animated: true, completion: nil)
|
|
}
|
|
}
|
|
|
|
/// Cancels the registration flow, handing control back to the onboarding coordinator.
|
|
@MainActor private func cancelRegistration() {
|
|
authenticationService.reset()
|
|
callback?(.cancel(.register))
|
|
}
|
|
|
|
// MARK: - Login
|
|
|
|
/// Shows the login screen.
|
|
@MainActor private func showLoginScreen() {
|
|
MXLog.debug("[AuthenticationCoordinator] showLoginScreen")
|
|
|
|
let homeserver = authenticationService.state.homeserver
|
|
let parameters = AuthenticationLoginCoordinatorParameters(navigationRouter: navigationRouter,
|
|
authenticationService: authenticationService,
|
|
loginMode: homeserver.preferredLoginMode)
|
|
let coordinator = AuthenticationLoginCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self, weak coordinator] result in
|
|
guard let self = self, let coordinator = coordinator else { return }
|
|
self.loginCoordinator(coordinator, didCallbackWith: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
if navigationRouter.modules.isEmpty {
|
|
navigationRouter.setRootModule(coordinator, popCompletion: nil)
|
|
} else {
|
|
navigationRouter.push(coordinator, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Shows the soft logout screen.
|
|
@MainActor private func showSoftLogoutScreen(_ credentials: MXCredentials) async {
|
|
MXLog.debug("[AuthenticationCoordinator] showSoftLogoutScreen")
|
|
|
|
guard let userId = credentials.userId else {
|
|
MXLog.failure("[AuthenticationCoordinator] showSoftLogoutScreen: Missing userId.")
|
|
displayError(message: VectorL10n.errorCommonMessage)
|
|
return
|
|
}
|
|
|
|
let store = MXFileStore(credentials: credentials)
|
|
let userDisplayName = await store.displayName(ofUserWithId: userId) ?? ""
|
|
|
|
let cryptoStore = MXRealmCryptoStore(credentials: credentials)
|
|
let keyBackupNeeded = (cryptoStore?.inboundGroupSessions(toBackup: 1) ?? []).count > 0
|
|
|
|
let softLogoutCredentials = SoftLogoutCredentials(userId: userId,
|
|
homeserverName: credentials.homeServerName() ?? "",
|
|
userDisplayName: userDisplayName,
|
|
deviceId: credentials.deviceId)
|
|
|
|
let parameters = AuthenticationSoftLogoutCoordinatorParameters(navigationRouter: navigationRouter,
|
|
authenticationService: authenticationService,
|
|
credentials: softLogoutCredentials,
|
|
keyBackupNeeded: keyBackupNeeded)
|
|
let coordinator = AuthenticationSoftLogoutCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self] result in
|
|
guard let self = self else { return }
|
|
switch result {
|
|
case .success(let session, let loginPassword):
|
|
self.password = loginPassword
|
|
self.authenticationType = .password
|
|
self.onSessionCreated(session: session, flow: .login)
|
|
case .clearAllData:
|
|
self.callback?(.clearAllData)
|
|
case .continueWithSSO(let provider):
|
|
self.presentSSOAuthentication(for: provider)
|
|
case .fallback:
|
|
self.showFallback(for: .login, deviceId: softLogoutCredentials.deviceId)
|
|
}
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.setRootModule(coordinator, popCompletion: nil)
|
|
}
|
|
|
|
/// Displays the next view in the flow based on the result from the registration screen.
|
|
@MainActor private func loginCoordinator(_ coordinator: AuthenticationLoginCoordinator,
|
|
didCallbackWith result: AuthenticationLoginCoordinatorResult) {
|
|
switch result {
|
|
case .continueWithSSO(let provider):
|
|
presentSSOAuthentication(for: provider)
|
|
case .success(let session, let loginPassword):
|
|
password = loginPassword
|
|
authenticationType = .password
|
|
onSessionCreated(session: session, flow: .login)
|
|
case .loggedInWithQRCode(let session, let securityCompleted):
|
|
authenticationType = .other
|
|
onSessionCreated(session: session, flow: .login, securityCompleted: securityCompleted)
|
|
case .fallback:
|
|
showFallback(for: .login)
|
|
}
|
|
}
|
|
|
|
// MARK: - Registration
|
|
|
|
/// Shows the registration screen.
|
|
@MainActor private func showRegistrationScreen() {
|
|
MXLog.debug("[AuthenticationCoordinator] showRegistrationScreen")
|
|
let homeserver = authenticationService.state.homeserver
|
|
let parameters = AuthenticationRegistrationCoordinatorParameters(navigationRouter: navigationRouter,
|
|
authenticationService: authenticationService,
|
|
registrationFlow: homeserver.registrationFlow,
|
|
loginMode: homeserver.preferredLoginMode)
|
|
let coordinator = AuthenticationRegistrationCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self, weak coordinator] result in
|
|
guard let self = self, let coordinator = coordinator else { return }
|
|
self.registrationCoordinator(coordinator, didCallbackWith: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
if navigationRouter.modules.isEmpty {
|
|
navigationRouter.setRootModule(coordinator, popCompletion: nil)
|
|
} else {
|
|
navigationRouter.push(coordinator, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Displays the next view in the flow based on the result from the registration screen.
|
|
@MainActor private func registrationCoordinator(_ coordinator: AuthenticationRegistrationCoordinator,
|
|
didCallbackWith result: AuthenticationRegistrationCoordinatorResult) {
|
|
switch result {
|
|
case .continueWithSSO(let provider):
|
|
presentSSOAuthentication(for: provider)
|
|
case .completed(let result, let registerPassword):
|
|
password = registerPassword
|
|
authenticationType = .password
|
|
handleRegistrationResult(result)
|
|
case .fallback:
|
|
showFallback(for: .register)
|
|
}
|
|
}
|
|
|
|
/// Shows the verify email screen.
|
|
@MainActor private func showVerifyEmailScreen(registrationWizard: RegistrationWizard) {
|
|
MXLog.debug("[AuthenticationCoordinator] showVerifyEmailScreen")
|
|
|
|
let parameters = AuthenticationVerifyEmailCoordinatorParameters(registrationWizard: registrationWizard,
|
|
homeserver: authenticationService.state.homeserver)
|
|
let coordinator = AuthenticationVerifyEmailCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self] result in
|
|
self?.registrationStageDidComplete(with: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.setRootModule(coordinator, hideNavigationBar: false, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
|
|
/// Shows the terms screen.
|
|
@MainActor private func showTermsScreen(terms: MXLoginTerms?, registrationWizard: RegistrationWizard) {
|
|
MXLog.debug("[AuthenticationCoordinator] showTermsScreen")
|
|
|
|
let localizedPolicies = terms?.policiesData(forLanguage: Bundle.mxk_language(), defaultLanguage: Bundle.mxk_fallbackLanguage())
|
|
let parameters = AuthenticationTermsCoordinatorParameters(registrationWizard: registrationWizard,
|
|
localizedPolicies: localizedPolicies ?? [],
|
|
homeserver: authenticationService.state.homeserver)
|
|
let coordinator = AuthenticationTermsCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self] result in
|
|
self?.registrationStageDidComplete(with: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.setRootModule(coordinator, hideNavigationBar: false, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
|
|
@MainActor private func showReCaptchaScreen(siteKey: String, registrationWizard: RegistrationWizard) {
|
|
MXLog.debug("[AuthenticationCoordinator] showReCaptchaScreen")
|
|
|
|
guard let homeserverURL = URL(string: authenticationService.state.homeserver.address) else {
|
|
MXLog.failure("[AuthenticationCoordinator] showReCaptchaScreen: The homeserver address is no longer a valid URL.")
|
|
displayError(message: VectorL10n.errorCommonMessage)
|
|
return
|
|
}
|
|
|
|
let parameters = AuthenticationReCaptchaCoordinatorParameters(registrationWizard: registrationWizard,
|
|
siteKey: siteKey,
|
|
homeserverURL: homeserverURL)
|
|
let coordinator = AuthenticationReCaptchaCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self] result in
|
|
self?.registrationStageDidComplete(with: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.setRootModule(coordinator, hideNavigationBar: false, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
|
|
/// Shows the verify email screen.
|
|
@MainActor private func showVerifyMSISDNScreen(registrationWizard: RegistrationWizard) {
|
|
MXLog.debug("[AuthenticationCoordinator] showVerifyMSISDNScreen")
|
|
|
|
let parameters = AuthenticationVerifyMsisdnCoordinatorParameters(registrationWizard: registrationWizard,
|
|
homeserver: authenticationService.state.homeserver)
|
|
let coordinator = AuthenticationVerifyMsisdnCoordinator(parameters: parameters)
|
|
coordinator.callback = { [weak self] result in
|
|
self?.registrationStageDidComplete(with: result)
|
|
}
|
|
|
|
coordinator.start()
|
|
add(childCoordinator: coordinator)
|
|
|
|
navigationRouter.setRootModule(coordinator, hideNavigationBar: false, animated: true) { [weak self] in
|
|
self?.remove(childCoordinator: coordinator)
|
|
}
|
|
}
|
|
|
|
/// Displays the next view in the registration flow.
|
|
@MainActor private func registrationStageDidComplete(with result: AuthenticationRegistrationStageResult) {
|
|
switch result {
|
|
case .completed(let result):
|
|
handleRegistrationResult(result)
|
|
case .cancel:
|
|
displayCancelConfirmation()
|
|
}
|
|
}
|
|
|
|
// MARK: - Registration Handlers
|
|
/// Determines the next screen to show from the flow result and pushes it.
|
|
@MainActor private func handleRegistrationResult(_ result: RegistrationResult) {
|
|
switch result {
|
|
case .success(let mxSession):
|
|
onSessionCreated(session: mxSession, flow: .register)
|
|
case .flowResponse(let flowResult):
|
|
MXLog.debug("[AuthenticationCoordinator] handleRegistrationResult: Missing stages - \(flowResult.missingStages)")
|
|
|
|
let homeserver = authenticationService.state.homeserver
|
|
guard let nextStage = homeserver.isMatrixDotOrg ? flowResult.nextUncompletedStageOrdered : flowResult.nextUncompletedStage else {
|
|
MXLog.failure("[AuthenticationCoordinator] There are no remaining stages.")
|
|
return
|
|
}
|
|
|
|
showStage(nextStage)
|
|
}
|
|
}
|
|
|
|
@MainActor private func showStage(_ stage: FlowResult.Stage) {
|
|
guard let registrationWizard = authenticationService.registrationWizard else {
|
|
MXLog.failure("[AuthenticationCoordinator] showStage: Missing the RegistrationWizard needed to complete the stage.")
|
|
displayError(message: VectorL10n.errorCommonMessage)
|
|
return
|
|
}
|
|
|
|
switch stage {
|
|
case .email:
|
|
showVerifyEmailScreen(registrationWizard: registrationWizard)
|
|
case .terms(_, let terms):
|
|
showTermsScreen(terms: terms, registrationWizard: registrationWizard)
|
|
case .reCaptcha(_, let siteKey):
|
|
showReCaptchaScreen(siteKey: siteKey, registrationWizard: registrationWizard)
|
|
case .msisdn:
|
|
showVerifyMSISDNScreen(registrationWizard: registrationWizard)
|
|
case .dummy:
|
|
MXLog.failure("[AuthenticationCoordinator] Attempting to perform the dummy stage.")
|
|
case .other:
|
|
MXLog.failure("[AuthenticationCoordinator] Attempting to perform an unsupported stage.")
|
|
showFallback(for: .register)
|
|
}
|
|
}
|
|
|
|
/// Handles the creation of a new session following on from a successful authentication.
|
|
@MainActor private func onSessionCreated(session: MXSession, flow: AuthenticationFlow, securityCompleted: Bool = false) {
|
|
self.session = session
|
|
|
|
guard !securityCompleted else {
|
|
callback?(.didLogin(session: session, authenticationFlow: flow, authenticationType: authenticationType ?? .other))
|
|
callback?(.didComplete)
|
|
return
|
|
}
|
|
|
|
if canPresentAdditionalScreens {
|
|
showLoadingAnimation()
|
|
}
|
|
|
|
let verificationListener = SessionVerificationListener(session: session, password: password)
|
|
|
|
verificationListener.completion = { [weak self] result in
|
|
guard let self = self else { return }
|
|
switch result {
|
|
case .needsVerification:
|
|
guard self.canPresentAdditionalScreens else {
|
|
MXLog.debug("[AuthenticationCoordinator] Delaying presentCompleteSecurity during onboarding.")
|
|
self.isWaitingToPresentCompleteSecurity = true
|
|
return
|
|
}
|
|
|
|
MXLog.debug("[AuthenticationCoordinator] Complete security")
|
|
self.presentCompleteSecurity()
|
|
case .authenticationIsComplete:
|
|
self.authenticationDidComplete()
|
|
}
|
|
}
|
|
|
|
verificationListener.start()
|
|
self.verificationListener = verificationListener
|
|
|
|
callback?(.didLogin(session: session, authenticationFlow: flow, authenticationType: authenticationType ?? .other))
|
|
}
|
|
|
|
// MARK: - Additional Screens
|
|
|
|
private func showFallback(for flow: AuthenticationFlow, deviceId: String? = nil) {
|
|
var url = authenticationService.fallbackURL(for: flow)
|
|
|
|
if let deviceId = deviceId {
|
|
// add deviceId as `device_id` into the url
|
|
guard var urlComponents = URLComponents(string: url.absoluteString) else {
|
|
MXLog.error("[AuthenticationCoordinator] showFallback: could not create url components")
|
|
return
|
|
}
|
|
var queryItems = urlComponents.queryItems ?? []
|
|
queryItems.append(URLQueryItem(name: "device_id", value: deviceId))
|
|
urlComponents.queryItems = queryItems
|
|
|
|
if let newUrl = urlComponents.url {
|
|
url = newUrl
|
|
} else {
|
|
MXLog.error("[AuthenticationCoordinator] showFallback: could not create url from components")
|
|
return
|
|
}
|
|
}
|
|
|
|
MXLog.debug("[AuthenticationCoordinator] showFallback for: \(flow), url: \(url)")
|
|
|
|
guard let fallbackVC = AuthFallBackViewController(url: url.absoluteString) else {
|
|
MXLog.error("[AuthenticationCoordinator] showFallback: could not create fallback view controller")
|
|
return
|
|
}
|
|
fallbackVC.delegate = self
|
|
let navController = RiotNavigationController(rootViewController: fallbackVC)
|
|
navController.navigationBar.topItem?.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel,
|
|
target: self,
|
|
action: #selector(dismissFallback))
|
|
navigationRouter.present(navController, animated: true)
|
|
}
|
|
|
|
@objc
|
|
private func dismissFallback() {
|
|
MXLog.debug("[AuthenticationCoorrdinator] dismissFallback")
|
|
|
|
guard let fallbackNavigationVC = navigationRouter.toPresentable().presentedViewController as? RiotNavigationController else {
|
|
return
|
|
}
|
|
fallbackNavigationVC.dismiss(animated: true)
|
|
authenticationService.reset()
|
|
}
|
|
|
|
/// Replace the contents of the navigation router with a loading animation.
|
|
private func showLoadingAnimation() {
|
|
let loadingViewController = LaunchLoadingViewController()
|
|
loadingViewController.modalPresentationStyle = .fullScreen
|
|
|
|
// Replace the navigation stack with the loading animation
|
|
// as there is nothing to navigate back to.
|
|
navigationRouter.setRootModule(loadingViewController)
|
|
}
|
|
|
|
/// Present the key verification screen modally.
|
|
private func presentCompleteSecurity() {
|
|
guard let session = session else {
|
|
MXLog.error("[AuthenticationCoordinator] presentCompleteSecurity: Unable to present security due to missing session.")
|
|
authenticationDidComplete()
|
|
return
|
|
}
|
|
|
|
let isNewSignIn = true
|
|
let cancellable = !session.vc_homeserverConfiguration().encryption.isSecureBackupRequired
|
|
let keyVerificationCoordinator = KeyVerificationCoordinator(session: session, flow: .completeSecurity(isNewSignIn), cancellable: cancellable)
|
|
|
|
keyVerificationCoordinator.delegate = self
|
|
let presentable = keyVerificationCoordinator.toPresentable()
|
|
presentable.presentationController?.delegate = self
|
|
navigationRouter.present(presentable, animated: true)
|
|
keyVerificationCoordinator.start()
|
|
add(childCoordinator: keyVerificationCoordinator)
|
|
}
|
|
|
|
/// Complete the authentication flow.
|
|
private func authenticationDidComplete() {
|
|
Task {
|
|
await MainActor.run { callback?(.didComplete) }
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - SSO
|
|
|
|
extension AuthenticationCoordinator: SSOAuthenticationPresenterDelegate {
|
|
/// Presents SSO authentication for the specified identity provider.
|
|
@MainActor private func presentSSOAuthentication(for identityProvider: SSOIdentityProvider) {
|
|
let service = SSOAuthenticationService(homeserverStringURL: authenticationService.state.homeserver.address)
|
|
let presenter = SSOAuthenticationPresenter(ssoAuthenticationService: service)
|
|
presenter.delegate = self
|
|
|
|
let transactionID = MXTools.generateTransactionId()
|
|
presenter.present(forIdentityProvider: identityProvider, with: transactionID, from: toPresentable(), animated: true)
|
|
|
|
ssoAuthenticationPresenter = presenter
|
|
ssoTransactionID = transactionID
|
|
authenticationType = .sso(identityProvider)
|
|
}
|
|
|
|
func ssoAuthenticationPresenter(_ presenter: SSOAuthenticationPresenter, authenticationSucceededWithToken token: String, usingIdentityProvider identityProvider: SSOIdentityProvider?) {
|
|
MXLog.debug("[AuthenticationCoordinator] SSO authentication succeeded.")
|
|
|
|
guard let loginWizard = authenticationService.loginWizard else {
|
|
MXLog.failure("[AuthenticationCoordinator] The login wizard was requested before getting the login flow.")
|
|
return
|
|
}
|
|
|
|
Task { await handleLoginToken(token, using: loginWizard) }
|
|
}
|
|
|
|
func ssoAuthenticationPresenter(_ presenter: SSOAuthenticationPresenter, authenticationDidFailWithError error: Error) {
|
|
MXLog.debug("[AuthenticationCoordinator] SSO authentication failed.")
|
|
|
|
Task { @MainActor in
|
|
displayError(message: error.localizedDescription)
|
|
ssoAuthenticationPresenter = nil
|
|
ssoTransactionID = nil
|
|
authenticationType = nil
|
|
}
|
|
}
|
|
|
|
func ssoAuthenticationPresenterDidCancel(_ presenter: SSOAuthenticationPresenter) {
|
|
MXLog.debug("[AuthenticationCoordinator] SSO authentication cancelled.")
|
|
ssoAuthenticationPresenter = nil
|
|
ssoTransactionID = nil
|
|
authenticationType = nil
|
|
}
|
|
|
|
/// Performs the last step of the login process for a flow that authenticated via SSO.
|
|
@MainActor private func handleLoginToken(_ token: String, using loginWizard: LoginWizard) async {
|
|
do {
|
|
let session = try await loginWizard.login(with: token)
|
|
onSessionCreated(session: session, flow: authenticationService.state.flow)
|
|
} catch {
|
|
MXLog.error("[AuthenticationCoordinator] Login with SSO token failed.")
|
|
displayError(message: error.localizedDescription)
|
|
authenticationType = nil
|
|
}
|
|
|
|
ssoAuthenticationPresenter = nil
|
|
ssoTransactionID = nil
|
|
}
|
|
}
|
|
|
|
// MARK: - AuthenticationServiceDelegate
|
|
extension AuthenticationCoordinator: AuthenticationServiceDelegate {
|
|
|
|
func authenticationService(_ service: AuthenticationService, needsPromptFor unrecognizedCertificate: Data?, completion: @escaping (Bool) -> Void) {
|
|
guard let certificate = unrecognizedCertificate else {
|
|
completion(false)
|
|
return
|
|
}
|
|
|
|
Task {
|
|
let trusted = await self.displayUnrecognizedCertificateAlert(for: certificate)
|
|
completion(trusted)
|
|
}
|
|
}
|
|
|
|
func authenticationService(_ service: AuthenticationService, didReceive ssoLoginToken: String, with transactionID: String) -> Bool {
|
|
guard let presenter = ssoAuthenticationPresenter, transactionID == ssoTransactionID else {
|
|
Task { await displayError(message: VectorL10n.errorCommonMessage) }
|
|
return false
|
|
}
|
|
|
|
guard let loginWizard = authenticationService.loginWizard else {
|
|
MXLog.failure("[AuthenticationCoordinator] The login wizard was requested before getting the login flow.")
|
|
return false
|
|
}
|
|
|
|
Task {
|
|
await handleLoginToken(ssoLoginToken, using: loginWizard)
|
|
await MainActor.run { presenter.dismiss(animated: true, completion: nil) }
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func authenticationService(_ service: AuthenticationService, didUpdateStateWithLink link: UniversalLink) {
|
|
if link.pathParams.first == "register" {
|
|
callback?(.cancel(.register))
|
|
} else {
|
|
callback?(.cancel(.login))
|
|
}
|
|
successIndicator = indicatorPresenter.present(.success(label: VectorL10n.done))
|
|
}
|
|
}
|
|
|
|
// MARK: - KeyVerificationCoordinatorDelegate
|
|
extension AuthenticationCoordinator: KeyVerificationCoordinatorDelegate {
|
|
func keyVerificationCoordinatorDidComplete(_ coordinator: KeyVerificationCoordinatorType, otherUserId: String, otherDeviceId: String) {
|
|
if let crypto = session?.crypto as? MXLegacyCrypto, let backup = crypto.backup,
|
|
!backup.hasPrivateKeyInCryptoStore || !backup.enabled {
|
|
MXLog.debug("[AuthenticationCoordinator][MXKeyVerification] requestAllPrivateKeys: Request key backup private keys")
|
|
crypto.setOutgoingKeyRequestsEnabled(true, onComplete: nil)
|
|
}
|
|
|
|
navigationRouter.dismissModule(animated: true) { [weak self] in
|
|
self?.authenticationDidComplete()
|
|
}
|
|
}
|
|
|
|
func keyVerificationCoordinatorDidCancel(_ coordinator: KeyVerificationCoordinatorType) {
|
|
navigationRouter.dismissModule(animated: true) { [weak self] in
|
|
self?.authenticationDidComplete()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - UIAdaptivePresentationControllerDelegate
|
|
extension AuthenticationCoordinator: UIAdaptivePresentationControllerDelegate {
|
|
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
|
|
// Prevent Key Verification from using swipe to dismiss
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Unused conformances
|
|
extension AuthenticationCoordinator {
|
|
func update(authenticationFlow: AuthenticationFlow) {
|
|
// unused
|
|
}
|
|
}
|
|
|
|
// MARK: - AuthFallBackViewControllerDelegate
|
|
extension AuthenticationCoordinator: AuthFallBackViewControllerDelegate {
|
|
func authFallBackViewController(_ authFallBackViewController: AuthFallBackViewController,
|
|
didLoginWith loginResponse: MXLoginResponse) {
|
|
let credentials = MXCredentials(loginResponse: loginResponse, andDefaultCredentials: nil)
|
|
let client = MXRestClient(credentials: credentials)
|
|
guard let session = MXSession(matrixRestClient: client) else {
|
|
MXLog.failure("[AuthenticationCoordinator] authFallBackViewController:didLogin: session could not be created")
|
|
return
|
|
}
|
|
authenticationType = .other
|
|
Task { await onSessionCreated(session: session, flow: authenticationService.state.flow) }
|
|
}
|
|
|
|
func authFallBackViewControllerDidClose(_ authFallBackViewController: AuthFallBackViewController) {
|
|
dismissFallback()
|
|
}
|
|
}
|