From 4e2878300f537b1d6af2892618652d06d1188af3 Mon Sep 17 00:00:00 2001 From: upgradetofreedom Date: Mon, 4 May 2020 18:27:27 +0000 Subject: [PATCH 001/199] Translated using Weblate (German) Currently translated at 96.4% (1611 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index c452fbc901..bc1f299d02 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2354,4 +2354,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Kopier es in deinen persönlichen Cloud-Speicher Verschlüsselung ist nicht aktiviert - +Dies kann nicht von einem mobilen Gerät erfolgen + + Wenn sich Raumversionen ändern + From eb6546d81c8b34ccebd8432840c84047899a26a7 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Mon, 4 May 2020 18:28:34 +0000 Subject: [PATCH 002/199] Translated using Weblate (German) Currently translated at 96.4% (1611 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bc1f299d02..cc95dae1d6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2357,4 +2357,10 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Dies kann nicht von einem mobilen Gerät erfolgen Wenn sich Raumversionen ändern + Verschlüsselung aktiviert + Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr & verifiziere Benutzer in deren Profil. + Die Verschlüsselung in diesem Raum wird nicht unterstützt + + Warte auf %s... + From 423f21b02e739bbe6cc7291387eedc96a0d7b1a6 Mon Sep 17 00:00:00 2001 From: aWeinzierl Date: Mon, 4 May 2020 18:34:16 +0000 Subject: [PATCH 003/199] Translated using Weblate (German) Currently translated at 96.4% (1611 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index cc95dae1d6..d4cf414b6f 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2363,4 +2363,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Warte auf %s... + Lege eine %s fest + Fehlerbehebung From 5fcf54cd573aec56d5489ee7ce86fe72a3db0fbf Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Mon, 4 May 2020 18:43:44 +0000 Subject: [PATCH 004/199] Translated using Weblate (German) Currently translated at 96.5% (1613 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index d4cf414b6f..7ee6a37ea6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2365,4 +2365,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Lege eine %s fest Fehlerbehebung + %s hat den Raum erstellt und konfiguriert. + + Fast geschaft! Zeigt das andere Gerät dasselbe Schild an\? From deb783f797cf1b1bfcca3c2418a1b46a2f2a3738 Mon Sep 17 00:00:00 2001 From: n3niu Date: Tue, 5 May 2020 13:27:57 +0000 Subject: [PATCH 005/199] Translated using Weblate (German) Currently translated at 96.5% (1613 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 7ee6a37ea6..1adf39f81d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2363,7 +2363,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Warte auf %s... - Lege eine %s fest + %s setzen Fehlerbehebung %s hat den Raum erstellt und konfiguriert. From b2f3ba220e8269e4a7e147975533801dc3b3cb2e Mon Sep 17 00:00:00 2001 From: Christopher Rossbach Date: Tue, 5 May 2020 13:34:25 +0000 Subject: [PATCH 006/199] Translated using Weblate (German) Currently translated at 96.5% (1614 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 1adf39f81d..bb7d9c18b9 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2367,5 +2367,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Fehlerbehebung %s hat den Raum erstellt und konfiguriert. - Fast geschaft! Zeigt das andere Gerät dasselbe Schild an\? + Fast geschaft! Zeigt das andere Gerät das gleiche Schild an\? From ac5db838803caf4acf023b1bee0777e0f6cee0f4 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Tue, 5 May 2020 13:35:03 +0000 Subject: [PATCH 007/199] Translated using Weblate (German) Currently translated at 96.5% (1614 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bb7d9c18b9..79b245ff3d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2368,4 +2368,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine %s hat den Raum erstellt und konfiguriert. Fast geschaft! Zeigt das andere Gerät das gleiche Schild an\? + Fast geschaft! Warte auf Bestätigung... From 1491bddb3b43f6fc550b60f514658b3491011ce3 Mon Sep 17 00:00:00 2001 From: Dirmin Date: Tue, 5 May 2020 08:17:45 +0000 Subject: [PATCH 008/199] Translated using Weblate (French) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/fr/ --- vector/src/main/res/values-fr/strings.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 190d781f2a..34434242ff 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2,7 +2,8 @@ - fr + utiliser pour récupérer la liste des langues prises en charge +\ndoit avoir la même valeur que le nom FR Messages @@ -588,8 +589,8 @@ Veuillez noter que cette action redémarrera l’application et pourra prendre u Vous n’aurez aucune adresse principale spécifiée pour ce salon. Le chiffrement est activé sur ce salon. Le chiffrement est désactivé sur ce salon. - Activer le chiffrement -(attention : ne peut pas être désactivé ensuite !) + Activer le chiffrement +\n(attention : ne peut pas être désactivé ensuite !) %s a essayé de charger un point précis dans l’historique du salon mais ne l’a pas trouvé. From d898bc71f73a8f77b0bbe54bb620f8f30d4f1eca Mon Sep 17 00:00:00 2001 From: Martijn de Boer Date: Wed, 6 May 2020 14:03:14 +0000 Subject: [PATCH 009/199] Translated using Weblate (Dutch) Currently translated at 68.4% (1144 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/nl/ --- vector/src/main/res/values-nl/strings.xml | 57 ++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) mode change 100755 => 100644 vector/src/main/res/values-nl/strings.xml diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml old mode 100755 new mode 100644 index eac681e604..d9156a9efe --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -1605,4 +1605,59 @@ U gebruikt geen identiteitsserver Er is geen identiteitsserver geconfigureerd. Dit is vereist om uw wachtwoord opnieuw in te stellen. - +Vorige versies van Riot hadden een veiligheidsfout die er voor kon zorgen dat je Identiteits Server (%1$s) toegang tot je account had. Indien je %2$s vertrouwt, dan kun je dit negeren; anders log je uit en weer in. +\n +\nLees meer details hier: +\nhttps://medium.com/@RiotChat/36b4792ea0d6 + + Het lijkt er op dat je probeert verbinding te maken met een andere thuisserver. Wil je uitloggen\? + + Bewerken + Beantwoorden + + Opnieuw proberen + Betreed een kamer om de applicatie te gebruiken + Heeft je een uitnodiging gestuurd + Uitgenodigd door %s + + Je bent helemaal bij! + Je hebt geen ongelezen berichten meer + Welkom thuis! + Ongelezen berichten inhalen + Gesprekken + Je directe gesprekken zullen hier worden weergegeven + Kamers + Je kamers zullen hier worden weergegeven + + Reacties + Bevestigen + Leuk vinden + Reactie Toevoegen + Reacties Bekijken + Reacties + + Gebeurtenis verwijderd door gebruiker + Gebeurtenis gemodereerd door gesprek beheerder + Laatst bewerkt door %1$s op %2$s + + + Niet correcte gebeurtenis, kan niet weergeven + Maak een nieuw gesprek aan + Geen netwerk. Controleer uw internet verbinding. + Wijzigen + Wijzig netwerk + Even wachten… + Alle Gemeenschappen + + Dit gesprek kan niet worden voorvertoond + De voorvertoning van wereld-leesbare gesprekken zijn nog niet ondersteund in RiotX + + Gesprekken + Directe Berichten + + Nieuw Gesprek + AANMAKEN + Gespreksnaam + Publiek + Iedereen zal dit gesprek kunnen toetreden + From b1ba4e393ed381e25940e61fe6e375d2082467ed Mon Sep 17 00:00:00 2001 From: Ville Ranki Date: Tue, 5 May 2020 08:00:53 +0000 Subject: [PATCH 010/199] Translated using Weblate (Finnish) Currently translated at 93.8% (1568 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/fi/ --- vector/src/main/res/values-fi/strings.xml | 209 +++++++++++++++++++++- 1 file changed, 208 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index d044bb5c1a..046508524d 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -2075,4 +2075,211 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Ei turvallinen Video. Kuva. - +Pyyntö annetun käyttäjä-ID:n vahvistamiseksi + Johonkin näistä on mahdollisesti murtauduttu: +\n +\n - Kotipalvelimesi +\n - Varmentamasi toisen käyttäjän kotipalvelin +\n - Sinun tai toisen käyttäjän Internet-yhteys +\n - Sinun tai toisen käyttäjän käyttämä laite + + Äänitiedosto + Tiedosto + + Varmennus lähetetty + Varmennuspyyntö + + + Varmenna istunto + Varmenna manuaalisesti + + Lue koodi toisen käyttäjän laitteesta varmentaaksenne toisenne tietoturvallisesti + Lue toisen käyttäjän koodi + Lukeminen ei onnistu + Vertailkaa emojeilla jos et ole toisen käyttäjän luona + + Varmenna vertaamalla emojeja + + Varmenna emojeilla + Jos koodin lukeminen ei onnistu, varmenna vertaamalla lyhyttä sarjaa emojeja. + + QR-koodi + + Varmenna %s + Varmennettu %s + Odotetaan käyttäjää %s… + Varmenna %s tarkistamalla teidän kummankin laitteella näkyvä koodi. +\n +\nJos mahdollista, tehkää tämä kummankin ollessa paikalla parhaan tietoturvan saavuttamiseksi. + Huoneessa olevat viesti eivät ole salattu osapuolten välisellä salauksella. + Huoneen viestit ovat salattu osapuolten välisellä salauksella. +\n +\nViestisi salataan niin, että vain sinä ja vastaanottaja pystytte avaamaan ne henkilökohtaisilla salausavaimillanne. + Tietoturva + Lisää + Huoneen asetukset + Tiedostojen lähetys + Ylläpitäjät + Moderaattorit + Käyttäjät + + Ylläpitäjä %1$s:ssä + Moderaattori %1$s:ssä + Siirry lukukuittaukseen + + RiotX ei osaa käsitellä tapahtumia joiden tyyppi on \'%1$s\' + RiotX ei osaa käsitellä viestejä joiden tyyppi on \'%1$s\' + RiotX ei osannut piirtää tapahtuman jonka tunniste on \'%1$s\' sisältöä + + Viimeaikaiset huoneet + Muut huoneet + + Lähettää annetun viestin väritettynä sateenkaaren väreillä + Ota käyttöön osapuolten välinen salaus + Salausta ei voi enää poistaa käytöstä sen jälkeen kun se on otettu käyttöön. + + Otetaanko salaus käyttöön\? + Salausta ei voi ottaa pois käytöstä sen jälkeen kun se on otettu käyttöön. Salattuja viestejä ei pysty lukemaan edes palvelin, vain ainoastaan huoneessa olijat. Salauksen käyttöönotto voi estää bottien ja siltojen toiminnan huoneessa. + Ota salaus käyttöön + + Salauksen mahdollistamiseksi varmenna %s tarkastamalla kertakäyttöinen koodi. + Tee tämä toisen käyttäjän ollessa läsnä tai käyttäkää toista viestintävälinettä tietoturvan varmistamiseksi. + + Verratkaa emojeja ja varmistakaa että ne ovat samassa järjestyksessä kummallakin. + Vertaa koodia joka näkyy toisen käyttäjän ruudulla. + Tämän käyttäjän kanssa käyty viestintä on nyt päästä päähän salattu ja sitä ei pysty kukaan ulkopuolinen vakoilemaan. + Istuntosi on nyt vahvistettu. Sillä on pääsy salattuihin viesteihisi ja muut käyttäjät näkevät sen luotettuna. + + + Aktiiviset istunnot + Näytä kaikki istunnot + Istuntojen hallinta + Kirjaudu ulos tästä istunnosta + + Ei salaukseen liittyvää tietoa + + Istunto on luotettu, koska olet vahvistanut sen: + Vahvista tämä istunto jotta se merkitään luotetuksi ja se saa pääsyn salattuihin viesteihin. Jos et ole kirjautunut tähän istuntoon, tunnuksesi on saattanut vuotaa hyökkääjälle: + + + %d käynnissä oleva istunto + %d käynnissä olevaa istuntoa + + + Varmenna tämä kirjautuminen + Muut käyttäjät eivät välttämättä luota siihen + Käytä olemassaolevaa istuntoa tämän istunnon varmentamiseksi jotta se saa oikeudet salattuihin viesteihin. + + + Varmenna + Varmennettu + Varoitus + + Ei saatu istuntoja + Istunnot + Luotettu + Ei luotettu + + "Tämä istunto on luotettu salattuun viestintään koska %1$s (%2$s) varmisti sen:" + %1$s (%2$s) kirjautui sisään uuteen istuntoon: + Tämän käyttäjän kanssa käyty viestintä merkitään virheiksi kunnes käyttäjä luottaa tähän istuntoon. Voit vaihtoehtoisesti käsin varmentaa sen. + + + Nollaa avaimet + + QR-koodi + + Melkein valmis! Näkyykä %s:lla sama kilven kuva\? + Kyllä + Ei + + Yhteys kotipalvelimeen on poikki + + Kehittäjän työkalut + + %d ääni + %d ääntä + + + %d ääni - lopulliset tulokset + %d ääntä - lopulliset tulokset + + Luo yksinkertaisen äänestyksen + Jos et pääse käsiksi olemassaolevaan istuntoon + + Uusi sisäänkirjautuminen + + Varoitus: + Poista… + Haluatko lähettää tämän liitteen %1$s\?:lle\? + + Lähetä kuva alkuperäisessä koossa + Lähetä kuvat alkuperäisessä koossa + + + Vahvista poisto + Haluatko varmasti poistaa tämän tapahtuman\? Huomaa, että jos poistat huoneen nimen tai otsikon muutostapahtuman, se voi perua muutoksen. + Anna syy + Käyttäjä poistanut tapahtuman, syynä: %1$s + Tapahtuma moderoitu huoneen ylläpitäjän toimesta, syynä: %1$s + + Avaimet ovat jo ajan tasalla! + + RiotX Android + + Avainpyynnöt + + Päivitä + + Uusi kirjautuminen. Olitko se sinä\? + Paina tarkastellaksesi ja varmentaaksesi + En ollut + Tilillesi saatetaan olla murtauduttu + + Jos perut, et voi lukea salattuja viestejäsi tällä laitteella eivätkä muut käyttäjät luota siihen + Jos perut, et voi lukea salattuja viestejäsi uudella laitteellasi eivätkä muut käyttäjät luota siihen + Varmenna laitteesi ohjelman asetuksista. + Vahvistus peruttu + + Palautussalasana + Tilin salasana + + Aseta %s + Vahvista %s + + Anna %s jatkaaksesi. + + Pura ja salaa salatut viestit ja luottamukset asettamalla %s + Anna %s uudestaan vahvistaaksesi sen. + Älä käytä tilisi salasanaa muualla. + + + Odota hetki, kiitos. + Alustetaan palautusta. + Palautusavaimesi + Valmista! + Pidä se turvassa + Lopeta + + Käytä %1$s:tä turvaverkkona jos onnistut unohtamaan %2$s:n. + + Julkaistaan luodut identiteettiavaimet + Luodaan salausavain salasanasta + Määritetään SSSS-oletusavain + Synkronoidaan pääavain + Synkronoidaan käyttäjän avain + Synkronoidaan allekirjoitusavain + Alustetaan avainten varmuuskopiointi + + + %2$s ja %1$s asetettu. +\n +\nPidä ne tallessa. Tarvitset ne salattujen viestiesi ja tietojesi avaamiseen, jos suljet kaikki istuntosi. + + Tulosta se jos mahdollista ja säilytä tuloste turvallisessa paikassa + Tallenna se muistitikulle tai varmuuskopiolevylle talteen + Kopioi se henkilökohtaiseen pilvitallennustilaasi + + Tätä ei pysty tekemään kännykällä + + From 13ebef334fed2ed795c7497b5ad7983bf02f0db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Wed, 6 May 2020 06:42:49 +0000 Subject: [PATCH 011/199] Translated using Weblate (French) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/fr/ --- vector/src/main/res/values-fr/strings.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 34434242ff..a8e72864f4 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2,8 +2,7 @@ - utiliser pour récupérer la liste des langues prises en charge -\ndoit avoir la même valeur que le nom + fr FR Messages From b53c073b9010594555637680473644f3ac604dff Mon Sep 17 00:00:00 2001 From: Christopher Rossbach Date: Tue, 5 May 2020 13:35:18 +0000 Subject: [PATCH 012/199] Translated using Weblate (German) Currently translated at 96.9% (1621 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 79b245ff3d..869fcbc6be 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2367,6 +2367,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Fehlerbehebung %s hat den Raum erstellt und konfiguriert. - Fast geschaft! Zeigt das andere Gerät das gleiche Schild an\? - Fast geschaft! Warte auf Bestätigung... + Fast geschafft! Zeigt das andere Gerät das gleiche Schild an\? + Fast geschafft! Warte auf Bestätigung… From 18de0ca9516f1e20bddd6a3f167f8adc7d90c711 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Tue, 5 May 2020 13:36:33 +0000 Subject: [PATCH 013/199] Translated using Weblate (German) Currently translated at 96.9% (1621 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 869fcbc6be..6afd29ccc1 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2369,4 +2369,15 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Fast geschafft! Zeigt das andere Gerät das gleiche Schild an\? Fast geschafft! Warte auf Bestätigung… + Verschlüsselte Nachrichten in 1:1 Chats + Nachricht… + + Verifiziere dich & andere, um eure Chats zu schützen + + Gebe deinen %s ein um fortzufahren. + Datei benutzen + + Dies ist kein gültiger Wiederherstellungsschlüssel + Bitte gib deinen Wiederherstellungsschlüssel ein + From f5fd0ac323db0b2fee4eacdb12b9dcb999e8e3c4 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Mon, 4 May 2020 14:30:49 +0000 Subject: [PATCH 014/199] Translated using Weblate (Hungarian) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/hu/ --- vector/src/main/res/values-hu/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index ca32ce03f2..8587b82515 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2382,4 +2382,10 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró Kérlek válassz jelszót. Ezt a hivatkozást ellenőrizd le még egyszer A közvetlen üzenetedet nem sikerült elkészíteni. Ellenőrizd azokat a felhasználókat akiket meg szeretnél hívni és próbáld újra. - +Használd a legújabb Riotot a másik eszközödön, úgy mint Riot Web, Asztali Riot, RiotX for Android vagy más eszközök közötti hitelesítést támogató másik Matrix klienst + Erősítsd meg ebben a bejelentkezésben a személyazonosságodat egy másik munkamenetből, hogy hozzáférhess a titkosított üzenetekhez. + %1$s hivatkozás egy másik oldalra visz: %2$s. +\n +\nFolytatod\? + + From afbda4ac28b8dfeb67a70f1370d83f0e7f1ccf88 Mon Sep 17 00:00:00 2001 From: kujaw Date: Tue, 5 May 2020 16:41:23 +0000 Subject: [PATCH 015/199] Translated using Weblate (Polish) Currently translated at 93.1% (1556 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/pl/ --- vector/src/main/res/values-pl/strings.xml | 64 ++++++++++++----------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index b0c1492acb..d36b9570b9 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -588,7 +588,7 @@ Możesz dodać adres e-mail do swojego profilu w ustawieniach. %d zmiana członkostwa %d zmiany członkostwa %d zmian członkostwa - + Rozmówca nie połączył się. @@ -615,13 +615,13 @@ Przyznaj dostęp w następnym oknie. Jeden aktywny członek Kilku aktywnych członków %d aktywnych członków - + 1 członek kilku członków %d członków - + Nie będziesz w stanie cofnąć tej zmiany, ponieważ przyznajesz użytkownikowi uprawnienia równe swoim. @@ -638,7 +638,7 @@ Jesteś pewien? Nowa wiadomość Kilka nowych wiadomości %d nowych wiadomości - + Może to oznaczać że ktoś zakłóca twoje połączenie, lub Twój telefon nie ufa certyfikatowi dostarczonemu przez zdalny serwer. @@ -652,13 +652,13 @@ Jesteś pewien? 1 pokój %d pokoje %d pokoi - + %1$s pokój znaleziony dla %2$s Kilka pokoi znalezionych dla %2$s %1$s pokoi znalezionych dla %2$s - + Wszystkie wiadomości (hałaśliwy) Wszystkie wiadomości @@ -804,13 +804,13 @@ Możesz to zrobić teraz lub później z poziomu ustawień aplikacji. 1 pokój %d pokoje %d pokoi - + 1 aktywny widżet %d aktywne widżety %d aktywnych widżetów - + Pokój %s nie jest widoczny. @@ -832,13 +832,13 @@ Czy chcesz dodać teraz kilka? 1 nieprzeczytana wiadomość powiadomienia %d nieprzeczytane wiadomości powiadomienia %d nieprzeczytanych wiadomości powiadomienia - + 1 nieprzeczytana wiadomość powiadomienia %d nieprzeczytane wiadomości powiadomienia %d nieprzeczytanych wiadomości powiadomienia - + %1$s w %2$s @@ -923,14 +923,14 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo 1 członek %d członków - + 1 pokój %d pokoje %d pokoi - + Kliknij tutaj, aby zobaczyć starsze wiadomości @@ -945,22 +945,22 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo 1 sekunda %d sek. - + 1 minuta %d min. - + 1 godzina %s godz. - + 1 dzień %d dni - + Pokazać wszystkie wiadomości od tego użytkownika? @@ -969,7 +969,7 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas. 1 zaznaczone %d zaznaczone %d zaznaczonych - + Wersja %s Podgląd mediów przed wysłaniem @@ -1040,7 +1040,7 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas. Czy chcesz wyrzucić tego użytkownika z rozmowy\? Czy chcesz wyrzucić tych użytkowników z rozmowy\? - + Formatowanie Markdown Pokaż zdarzenia dołączenia i wyjścia @@ -1167,7 +1167,7 @@ Spróbuj uruchomić ponownie aplikację. Przywrócono kopię zapasową z %d kluczem. Przywrócono kopię zapasową z %d kluczami. - + Użyj kopii zapasowej klucza Uruchamianie… (%1$d z %2$d) @@ -1486,12 +1486,12 @@ Spróbuj uruchomić ponownie aplikację. %1$s: 1 wiadomość %1$s: %2$d wiadomości - + %d powiadomienie %d powiadomień - + Nowe wydarzenie @@ -1621,7 +1621,7 @@ Spróbuj uruchomić ponownie aplikację. Kopiowanie %d klucza… Kopiowanie %d kluczy… - + Nieprawidłowa odpowiedź funkcji autoodkrywania serwera domowego @@ -1779,7 +1779,7 @@ Spróbuj uruchomić ponownie aplikację. 1 użytkownik odczytał %d użytkowników odczytało - + Wystąpił błąd poczas otrzymywania załącznika. @@ -1924,7 +1924,7 @@ Spróbuj uruchomić ponownie aplikację. Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundę… Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundy… - + Wylogowałeś(-łaś) się @@ -2042,7 +2042,7 @@ Spróbuj uruchomić ponownie aplikację. Jedna osoba %1$d osób - + Opuszczanie pokoju… @@ -2117,7 +2117,7 @@ Spróbuj uruchomić ponownie aplikację. %d aktywna sesja %d aktywnych sesji - + Zweryfikuj tą sesję @@ -2154,12 +2154,12 @@ Spróbuj uruchomić ponownie aplikację. %d głos %d głosów - + %d głos - wyniki końcowe %d głosów - wyniki końcowe - + Wybrana Opcja Tworzy prostą ankietę @@ -2178,7 +2178,7 @@ Spróbuj uruchomić ponownie aplikację. Wyślij obraz w oryginalnym rozmiarze Wyślij obrazy w oryginalnym rozmiarze - + Potwierdź Usunięcie @@ -2239,4 +2239,8 @@ Spróbuj uruchomić ponownie aplikację. Tryb programisty aktywuje ukryte funkcje i może również spowodować, że aplikacja będzie mniej stabilna. Tylko dla programistów! Wiadomości w tym pokoju nie są szyfrowane end-to-end. Przesłane pliki - +Prośby o klucze + + Odblokuj historię zaszyfrowanych wiadomości + + From b6af2269d2f8f2d6bbba80fc4032ac089aded151 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 6 May 2020 18:14:27 +0000 Subject: [PATCH 016/199] Translated using Weblate (Albanian) Currently translated at 99.6% (1665 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sq/ --- vector/src/main/res/values-sq/strings.xml | 77 +++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 970587e702..10ecd0af4d 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -592,7 +592,7 @@ Importo Jepni frazëkalimin Fshehtëzoje vetëm për sesione të verifikuar - JO i verifikuar + Jo i verifikuar I verifikuar Në Listë të Zezë @@ -916,8 +916,8 @@ Hiqi verifikimin Hiqe nga listë e zezë - Që të verifikoni se këtij sesioni mund t’i zihet besë, ju lutemi, lidhuni me të zotët e saj përmes ndonjë rruge tjetër (p.sh., personalisht, ose përmes një thirrjeje telefonike) dhe pyetini nëse përputhet apo jo kyçi që shohin te Rregullime të tyret të Përdoruesit për këtë sesion me kyçin më poshtë: - Nëse përputhet, shtypni butonin e verifikimit më poshtë. Nëse jo, atëherë dikush tjetër po e përgjon këtë sesion dhe duhet ta kaloni në listë të zezë. Në të ardhmen, ky proces verifikimi do të jetë më i sofistikuar. + Ripohojeni duke krahasuar sa vijon me Rregullimet e Përdoruesit te sesioni juaj tjetër: + Nëse s’përputhen, siguria e komunikimeve tuaja mund të jetë komprometuar. URL Shërbyesi Home 1 dhomë @@ -2182,7 +2182,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Rifreskoje - Sesion i Ri + Hyrje e re. Ju qetë\? Prekeni, që ta shqyrtoni & verifikoni Përdoreni këtë sesion që të verifikoni atë të riun tuaj, duke i akorduar hyrje te mesazhe të fshehtëzuar. Ky s’qeshë unë @@ -2278,4 +2278,73 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Emër përdoruesi dhe/ose fjalëkalim i pasaktë. Fjalëkalimi i dhënë fillon ose mbaron me hapësirë, ju lutemi, kontrollojeni. + + Po publikohen kyçe të krijuar identiteti + Mesazh… + + Ka të gatshëm përmirësim fshehtëzimi + Verifikoni veten & të tjerët, që t’i mbani bisedat tuaja të sigurta + + Që të vazhdohet, jepni %s tuaj + Përdor Kartelë + + Jepni %s + Frazëkalim Rikthimesh + S’është kyç rimarrjesh i vlefshëm + Ju lutemi, jepni një kyç rimarrjesh + + Po kontrollohet Kyç kopjeruajtjeje + Po kontrollohet Kyç kopjeruajtjeje (%s) + Po prodhohet kyç SSSS nga frazëkalim + Po prodhohet kyç SSSS prej frazëkalimi (%s) + Po prodhohet kyç SSSS nga kyç rimarrjesh + Po depozitohet e fshehtë kopjeruajtjeje kyçesh në SSSS + %1$s (%2$s) + + Që të vazhdohet, jepni Frazëkalim Kopjeruajtje Kyçesh. + përdorni kyçin tuaj të rimarrjeve të Kopjeruajtjes së Kyçeve + S’dihet Frazëkalimi juaj i Kopjeruajtjes së Kyçeve, mundeni të %s. + Kyç rimarrjesh Kopjeruajtjesh Kyçesh + + Pengo foto ekrani të aplikacionit + Aktivizimi i këtij rregullimi shton FLAG_SECURE te krejt Veprimtaritë. Që ndryshimi të hyjë në fuqi, rinisni aplikacionin. + + Te Galeria u shtua kartelë media + S’u shtua dot kartelë media te Galeria + Caktoni një fjalëkalim të ri llogarie… + + Përdorni Riot-in më të ri në pajisjet tuaja të tjera, Riot Web, Riot Desktop, Riot iOS, RiotX për Android, ose ose një tjetër klient Matrix i aftë për <em>cross-signing</em + Riot Web +\nRiot Desktop + Riot iOS +\nRiot X për Android + ose një tjetër klient Matrix i aftë për <em>cross-signing</em + Përdorni Riot-in më të ri në pajisjet tuaja të tjera: + Mbulohet vetëm për dhoma të fshehtëzuara + Përdorni %1$s tuaj ose përdorni %2$s tuaj që të vazhdohet. + Përdorni Kyçin Rimarrjesh + Përzgjidhni Kyçin tuaj të Rimarrjeve, ose jepeni dorazi duke e shtypur ose duke e ngjitur prej të papastrës tuaj + Kopjeruajtja s’u shfshehtëzua dot me këtë Kyç Rimarrjesh: ju lutemi, verifikoni se keni dhënë Kyçin e saktë të Rimarrjeve. + S\"u arrit të hyhet në depozitë të sigurt + + Të pafshehtëzuara + Fshehtëzuar nga një pajisje e paverifikuar + Shqyrtojini kur të jeni i futur + Verifikoni krejt sesionet tuaj që të siguroheni se llogaria & mesazhet tuaja janë të sigurt + Verifikoni kredencialet e reja për hyrje te llogaria juaj: %1$s + + Verifikojeni Dorazi përmes Teksti + Verifikoni kredenciale hyrjeje + Verifikojeni përmes Emoji-sh + Ripohoni identitetin tuaj duke verifikuar këto kredenciale hyrjesh prej një nga sesionet tuaj të tjerë, duke i akorduar hyrje te mesazhet e fshehtëzuar. + Vërini shenjë si i Besuar + + Ju lutemi zgjidhni një emër përdoruesi. + Ju lutemi, zgjidhni një fjalëkalim. + Kontrollojeni edhe një herë këtë lidhje + Lidhja %1$s po ju shpie te një tjetër sajt: %2$s. +\n +\nJeni i sigurt se doni të vazhdohet\? + + S’e krijuam dot DM-në tuaj. Ju lutemi, kontrolloni përdoruesit që doni të ftoni dhe riprovoni. From 439aa7854c409134051f9618709884473e69a22f Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:22:44 +0000 Subject: [PATCH 017/199] Translated using Weblate (German) Currently translated at 97.1% (1623 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 6afd29ccc1..f96cfda19c 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2380,4 +2380,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Dies ist kein gültiger Wiederherstellungsschlüssel Bitte gib deinen Wiederherstellungsschlüssel ein + Verschlüsselte Nachrichten und Verifizierungen mit einer %s absichern und entsperren. From d70a09ded85dcdd457ce5ba40cbd7a2125737b7e Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:26:12 +0000 Subject: [PATCH 018/199] Translated using Weblate (German) Currently translated at 97.1% (1623 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f96cfda19c..ce06727e9b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2381,4 +2381,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Bitte gib deinen Wiederherstellungsschlüssel ein Verschlüsselte Nachrichten und Verifizierungen mit einer %s absichern und entsperren. + Das setzen einer Wiederherstellungspassphrase ermöglicht das ver- & entschlüsseln von Nachrichten und Vertrauen. +\n +\nWenn du kein Nachrichtenpassword setzen willst, erzeuge stattdessen einen Nachrichtenschlüssel. From dd46798bda7597e3b289e638856820126787b964 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:27:28 +0000 Subject: [PATCH 019/199] Translated using Weblate (German) Currently translated at 97.1% (1624 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index ce06727e9b..11425b8286 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2381,7 +2381,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Bitte gib deinen Wiederherstellungsschlüssel ein Verschlüsselte Nachrichten und Verifizierungen mit einer %s absichern und entsperren. - Das setzen einer Wiederherstellungspassphrase ermöglicht das ver- & entschlüsseln von Nachrichten und Vertrauen. + Das setzen eines Wiederherstellungspassworts ermöglicht das sichern & entsperren von verschlüsselten Nachrichten und Verifizierungen. \n -\nWenn du kein Nachrichtenpassword setzen willst, erzeuge stattdessen einen Nachrichtenschlüssel. +\nWenn du kein Nachrichtenpasswort setzen willst, erzeuge stattdessen einen Nachrichtenschlüssel. From a43ca5925c1b42b9a438186d48769f2ff7168ff1 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:27:42 +0000 Subject: [PATCH 020/199] Translated using Weblate (German) Currently translated at 97.1% (1624 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 11425b8286..11cdf20cc5 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2384,4 +2384,8 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Das setzen eines Wiederherstellungspassworts ermöglicht das sichern & entsperren von verschlüsselten Nachrichten und Verifizierungen. \n \nWenn du kein Nachrichtenpasswort setzen willst, erzeuge stattdessen einen Nachrichtenschlüssel. + Das setzen einer Wiederherstellungspassphrase ermöglicht das ver- & entschlüsseln von Nachrichten und Vertrauen. +\n + + From e9bb95b3b378e8699cb62d15e81fba186aa99c35 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:28:41 +0000 Subject: [PATCH 021/199] Translated using Weblate (German) Currently translated at 97.3% (1627 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 11cdf20cc5..517484cb8b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2384,8 +2384,8 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Das setzen eines Wiederherstellungspassworts ermöglicht das sichern & entsperren von verschlüsselten Nachrichten und Verifizierungen. \n \nWenn du kein Nachrichtenpasswort setzen willst, erzeuge stattdessen einen Nachrichtenschlüssel. - Das setzen einer Wiederherstellungspassphrase ermöglicht das ver- & entschlüsseln von Nachrichten und Vertrauen. -\n + Das setzen eines Wiederherstellungspassworts ermöglicht das sichern & entsperren von verschlüsselten Nachrichten und Verifizierungen. + Verschlüsselungsupgrade verfügbar From 19e1da121675f5c8f8af385e20844a92e90e5ccd Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:30:12 +0000 Subject: [PATCH 022/199] Translated using Weblate (German) Currently translated at 97.3% (1627 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 517484cb8b..83429ee5f6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2388,4 +2388,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verschlüsselungsupgrade verfügbar + %s eingeben + Wiederherstellungs-Passphrase From daae030134ad7098e7f6b12c1e44f3d60079d64f Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:30:27 +0000 Subject: [PATCH 023/199] Translated using Weblate (German) Currently translated at 97.5% (1630 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 83429ee5f6..805dbf831b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2389,5 +2389,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verschlüsselungsupgrade verfügbar %s eingeben - Wiederherstellungs-Passphrase + Wiederherstellungspasswort From e1884e7c73ceec7f1028213a48a75f350840d766 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:30:38 +0000 Subject: [PATCH 024/199] Translated using Weblate (German) Currently translated at 97.5% (1630 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 805dbf831b..d52380fe81 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2390,4 +2390,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verschlüsselungsupgrade verfügbar %s eingeben Wiederherstellungspasswort + Überprüfe Wiederherstellungsschlüssel + Überprüfe Sicherungsstatus (%s) + Erzeuge Kurven-Schlüssel From b48113a3535af75754d294ad655ece701b4facc6 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:32:01 +0000 Subject: [PATCH 025/199] Translated using Weblate (German) Currently translated at 97.5% (1631 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index d52380fe81..747b1ea6bd 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2392,5 +2392,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Wiederherstellungspasswort Überprüfe Wiederherstellungsschlüssel Überprüfe Sicherungsstatus (%s) - Erzeuge Kurven-Schlüssel + Erzeuge Kurvenschlüssel From da4b0290930974b8992ed1ecfef1b58fad0062fc Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:32:12 +0000 Subject: [PATCH 026/199] Translated using Weblate (German) Currently translated at 97.5% (1631 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 747b1ea6bd..70ccd8a17d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2393,4 +2393,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Überprüfe Wiederherstellungsschlüssel Überprüfe Sicherungsstatus (%s) Erzeuge Kurvenschlüssel + Generiere SSSS Schlüssel aus der Passphrase From 8b3403c115d8946c8b82271f2dab2d03ab647cc4 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:32:22 +0000 Subject: [PATCH 027/199] Translated using Weblate (German) Currently translated at 97.6% (1632 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 70ccd8a17d..f4368ed7dc 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2393,5 +2393,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Überprüfe Wiederherstellungsschlüssel Überprüfe Sicherungsstatus (%s) Erzeuge Kurvenschlüssel - Generiere SSSS Schlüssel aus der Passphrase + Generiere SSSS Schlüssel aus dem Passwort From 1e2d267fec377c5d7b0107d572f8911372957ec7 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:32:27 +0000 Subject: [PATCH 028/199] Translated using Weblate (German) Currently translated at 97.6% (1632 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f4368ed7dc..89cb67f461 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2394,4 +2394,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Überprüfe Sicherungsstatus (%s) Erzeuge Kurvenschlüssel Generiere SSSS Schlüssel aus dem Passwort + Generiere SSSS Schlüssel aus der Passphrase (%s) From e1286a0ed4222bdf7b9ddf48829cef78b4a25067 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:32:36 +0000 Subject: [PATCH 029/199] Translated using Weblate (German) Currently translated at 97.7% (1634 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 89cb67f461..f8fd794a59 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2394,5 +2394,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Überprüfe Sicherungsstatus (%s) Erzeuge Kurvenschlüssel Generiere SSSS Schlüssel aus dem Passwort - Generiere SSSS Schlüssel aus der Passphrase (%s) + Generiere SSSS Schlüssel aus dem Passwort (%s) From 7966f6e30870364d2b2c83e76835a025dc656e09 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:32:51 +0000 Subject: [PATCH 030/199] Translated using Weblate (German) Currently translated at 97.7% (1634 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f8fd794a59..0b0c4ed847 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2395,4 +2395,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Erzeuge Kurvenschlüssel Generiere SSSS Schlüssel aus dem Passwort Generiere SSSS Schlüssel aus dem Passwort (%s) + Generiere SSSS Schlüssel aus dem Wiederherstellungsschlüssel + "Speichere Schlüssel-Backup Schlüssel in SSSS" From 7e3413eda799065eb227036304f40c7d077981cc Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:34:42 +0000 Subject: [PATCH 031/199] Translated using Weblate (German) Currently translated at 97.8% (1636 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 0b0c4ed847..310f552877 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2396,5 +2396,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Generiere SSSS Schlüssel aus dem Passwort Generiere SSSS Schlüssel aus dem Passwort (%s) Generiere SSSS Schlüssel aus dem Wiederherstellungsschlüssel - "Speichere Schlüssel-Backup Schlüssel in SSSS" + Speichere Schlüsselbackup Schlüssel in SSSS From e97d56580994a2d4a3e8b91280369c177d8bc046 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:34:53 +0000 Subject: [PATCH 032/199] Translated using Weblate (German) Currently translated at 97.8% (1636 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 310f552877..5cea7204a1 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2397,4 +2397,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Generiere SSSS Schlüssel aus dem Passwort (%s) Generiere SSSS Schlüssel aus dem Wiederherstellungsschlüssel Speichere Schlüsselbackup Schlüssel in SSSS + %1$s (%2$s) + + Gebe dein Password für das Schlüssel-Backup ein um fortzufahren. From 89629ffe93c357a957f4c32ca7544c35a12de4a9 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:35:28 +0000 Subject: [PATCH 033/199] Translated using Weblate (German) Currently translated at 97.9% (1637 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 5cea7204a1..c884f745e4 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2399,5 +2399,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Speichere Schlüsselbackup Schlüssel in SSSS %1$s (%2$s) - Gebe dein Password für das Schlüssel-Backup ein um fortzufahren. + Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. From fc8ab0d462bb6296c696cbf225dc5f1945887047 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:35:48 +0000 Subject: [PATCH 034/199] Translated using Weblate (German) Currently translated at 97.9% (1637 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index c884f745e4..58ebc0254d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2400,4 +2400,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine %1$s (%2$s) Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. + nutze deinen Schlüssel-Backup Wiederherstellungsschlüssel From 2d3e23ee1164809f24bf6f3ee1af7c07e5a36395 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:36:10 +0000 Subject: [PATCH 035/199] Translated using Weblate (German) Currently translated at 98.0% (1638 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 58ebc0254d..52bff656b5 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2400,5 +2400,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine %1$s (%2$s) Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. - nutze deinen Schlüssel-Backup Wiederherstellungsschlüssel + nutze deinen Schlüsselbackup Wiederherstellungsschlüssel From c3b662fa1f06e7896c87b922018f1ebd129757f6 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:39:44 +0000 Subject: [PATCH 036/199] Translated using Weblate (German) Currently translated at 98.0% (1638 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 52bff656b5..5204edfceb 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2401,4 +2401,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. nutze deinen Schlüsselbackup Wiederherstellungsschlüssel + Wenn du deine Schlüssel-Backup Passphrase nicht weißt, kannst du %s. From 361f0415bbd66ae5c347a32238fa5b09a73ee962 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:40:01 +0000 Subject: [PATCH 037/199] Translated using Weblate (German) Currently translated at 98.0% (1639 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 5204edfceb..171030941d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2401,5 +2401,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. nutze deinen Schlüsselbackup Wiederherstellungsschlüssel - Wenn du deine Schlüssel-Backup Passphrase nicht weißt, kannst du %s. + Wenn du dein Schlüsselbackup Passwort nicht weißt, kannst du %s. From e13915b0c740365c10c5855f0040b878ba366332 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:40:11 +0000 Subject: [PATCH 038/199] Translated using Weblate (German) Currently translated at 98.0% (1639 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 171030941d..684a78b02d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2402,4 +2402,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. nutze deinen Schlüsselbackup Wiederherstellungsschlüssel Wenn du dein Schlüsselbackup Passwort nicht weißt, kannst du %s. + Schlüssel-Backup Wiederherstellungsschlüssel + From 0e0b7245358a748144b46810a29ff1872a04c341 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:40:19 +0000 Subject: [PATCH 039/199] Translated using Weblate (German) Currently translated at 98.1% (1640 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 684a78b02d..1b30439b3b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2402,6 +2402,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Gib dein Passwort für das Schlüsselbackup ein, um fortzufahren. nutze deinen Schlüsselbackup Wiederherstellungsschlüssel Wenn du dein Schlüsselbackup Passwort nicht weißt, kannst du %s. - Schlüssel-Backup Wiederherstellungsschlüssel + Schlüsselbackup Wiederherstellungsschlüssel From 6d61848ed668ead824f599b0e78cc3e0a7e85b6e Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:42:45 +0000 Subject: [PATCH 040/199] Translated using Weblate (German) Currently translated at 98.1% (1640 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 1b30439b3b..5032037f69 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2404,4 +2404,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Wenn du dein Schlüsselbackup Passwort nicht weißt, kannst du %s. Schlüsselbackup Wiederherstellungsschlüssel + Verhindere Screenshots der Anwendung From 2d31402cf0c2353cabb386e6b02c8fdf0b7af1f4 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:42:56 +0000 Subject: [PATCH 041/199] Translated using Weblate (German) Currently translated at 98.1% (1641 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 5032037f69..e558e90ed6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2404,5 +2404,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Wenn du dein Schlüsselbackup Passwort nicht weißt, kannst du %s. Schlüsselbackup Wiederherstellungsschlüssel - Verhindere Screenshots der Anwendung + Verhindere Screenshots innerhalb der Anwendung From 2aa8512f6febecf5e605357e55509f70bcb6764e Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:44:42 +0000 Subject: [PATCH 042/199] Translated using Weblate (German) Currently translated at 98.1% (1641 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index e558e90ed6..bbe062fc99 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2405,4 +2405,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Schlüsselbackup Wiederherstellungsschlüssel Verhindere Screenshots innerhalb der Anwendung + Das aktivieren dieser Einstellung setzt das FLAG_SECURE in allen Aktivitäten. Starte die Anwendung neu, damit die Änderung wirksam wird. + From f1d2abc9b103fb7639b62cc7970ab2e1ef3d148c Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:53:27 +0000 Subject: [PATCH 043/199] Translated using Weblate (German) Currently translated at 98.3% (1644 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bbe062fc99..b79742ab9e 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2405,6 +2405,8 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Schlüsselbackup Wiederherstellungsschlüssel Verhindere Screenshots innerhalb der Anwendung - Das aktivieren dieser Einstellung setzt das FLAG_SECURE in allen Aktivitäten. Starte die Anwendung neu, damit die Änderung wirksam wird. + Das Aktivieren dieser Einstellung setzt das FLAG_SECURE in allen Aktivitäten. Starte die Anwendung neu, damit die Änderung wirksam wird. + Datei wurde der Galerie hinzugefügt + Datei konnte nicht zur Galerie hinzugefügt werden From 89fb2cf39137b97ce3898b4542a7e83c9f228477 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:55:42 +0000 Subject: [PATCH 044/199] Translated using Weblate (German) Currently translated at 98.3% (1644 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index b79742ab9e..3e9c6bd762 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2409,4 +2409,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Datei wurde der Galerie hinzugefügt Datei konnte nicht zur Galerie hinzugefügt werden + Neues Benutzerkonto-Passwort festlegen… + From 2f5fe59aa6231e04463fe99a58262d383d47c11f Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:55:58 +0000 Subject: [PATCH 045/199] Translated using Weblate (German) Currently translated at 98.7% (1650 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 3e9c6bd762..8991426c5b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2409,6 +2409,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Datei wurde der Galerie hinzugefügt Datei konnte nicht zur Galerie hinzugefügt werden - Neues Benutzerkonto-Passwort festlegen… + Neues Benutzerpasswort festlegen… From be94921918da5edb16080208c2a6eb46b14debeb Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 21:56:57 +0000 Subject: [PATCH 046/199] Translated using Weblate (German) Currently translated at 98.7% (1650 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 8991426c5b..2a9ae7697e 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2411,4 +2411,12 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Datei konnte nicht zur Galerie hinzugefügt werden Neues Benutzerpasswort festlegen… + Nutze die neueste Version von Riot auf deinen anderen Geräten, Riot Web, Riot Desktop, Riot iOS, RiotX für Android oder einen anderen cross-signing fähigen Matrix client + Riot Web +\nRiot Desktop + Riot iOS +\nRiot X für Android + oder einen anderen cross-signing fähigen Matrix Client + Nutze die neueste Version von Riot auf deinen anderen Geräten: + Erzwingt, dass die aktuell ausgehende Gruppen-Sitzung in einem verschlüsseltem Raum verworfen wird From fa004c9d936bef19c527b46e5f42748b449b4ca7 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:00:54 +0000 Subject: [PATCH 047/199] Translated using Weblate (German) Currently translated at 98.8% (1652 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 2a9ae7697e..d14b1d425e 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2418,5 +2418,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine \nRiot X für Android oder einen anderen cross-signing fähigen Matrix Client Nutze die neueste Version von Riot auf deinen anderen Geräten: - Erzwingt, dass die aktuell ausgehende Gruppen-Sitzung in einem verschlüsseltem Raum verworfen wird + Erzwingt das Verferfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum From 53ba1c206817f32bc7208cc9381180088a96a682 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:01:02 +0000 Subject: [PATCH 048/199] Translated using Weblate (German) Currently translated at 98.8% (1652 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index d14b1d425e..0b465650a6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2419,4 +2419,6 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine oder einen anderen cross-signing fähigen Matrix Client Nutze die neueste Version von Riot auf deinen anderen Geräten: Erzwingt das Verferfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum + Wird nur in verschlüsselten Räumen unterstützt + Benutze deine %1$s oder deinen %2$s um fortzufahren. From 26105dc25f733c349716d77885dd50c2b6ab873b Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:03:19 +0000 Subject: [PATCH 049/199] Translated using Weblate (German) Currently translated at 98.9% (1653 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 0b465650a6..ec0afc1520 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2420,5 +2420,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Nutze die neueste Version von Riot auf deinen anderen Geräten: Erzwingt das Verferfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum Wird nur in verschlüsselten Räumen unterstützt - Benutze deine %1$s oder deinen %2$s um fortzufahren. + Benutze dein %1$s oder deinen %2$s um fortzufahren. From 14e8bbcec6bc381e4e5d208a055ba5a5d0f6e5a5 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:03:31 +0000 Subject: [PATCH 050/199] Translated using Weblate (German) Currently translated at 98.9% (1653 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index ec0afc1520..0db2c4017e 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2421,4 +2421,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Erzwingt das Verferfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum Wird nur in verschlüsselten Räumen unterstützt Benutze dein %1$s oder deinen %2$s um fortzufahren. + Nutze Wiederherstellungsschlüssel From be9fa268b1433fd2cb4aa69abc2e9a06229f1ce2 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:03:45 +0000 Subject: [PATCH 051/199] Translated using Weblate (German) Currently translated at 98.9% (1654 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 0db2c4017e..dbef5fcf93 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2421,5 +2421,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Erzwingt das Verferfen der aktuell ausgehende Gruppensitzung in einem verschlüsseltem Raum Wird nur in verschlüsselten Räumen unterstützt Benutze dein %1$s oder deinen %2$s um fortzufahren. - Nutze Wiederherstellungsschlüssel + Wiederherstellungsschlüssel verwenden From 717e5161a6865cd9e5ccbf48f876dfc5220ef32f Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:04:09 +0000 Subject: [PATCH 052/199] Translated using Weblate (German) Currently translated at 98.9% (1654 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index dbef5fcf93..8f610068e8 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2422,4 +2422,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Wird nur in verschlüsselten Räumen unterstützt Benutze dein %1$s oder deinen %2$s um fortzufahren. Wiederherstellungsschlüssel verwenden + Wähle deinen Wiederherstellungsschüssel, geben ihn ein oder füge ihn aus der Zwischenablage ein From d51ee19f3fb9a2cd893df0bbaac65672afab5635 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:05:07 +0000 Subject: [PATCH 053/199] Translated using Weblate (German) Currently translated at 99.3% (1660 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 8f610068e8..120f06f98b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2422,5 +2422,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Wird nur in verschlüsselten Räumen unterstützt Benutze dein %1$s oder deinen %2$s um fortzufahren. Wiederherstellungsschlüssel verwenden - Wähle deinen Wiederherstellungsschüssel, geben ihn ein oder füge ihn aus der Zwischenablage ein + Wähle deinen Wiederherstellungsschüssel, gib ihn ein oder füge ihn aus der Zwischenablage ein From d6fe6e44bd3a299d229345271cc62f7be4404ed7 Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:05:34 +0000 Subject: [PATCH 054/199] Translated using Weblate (German) Currently translated at 99.3% (1660 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 120f06f98b..6ef0289a21 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2423,4 +2423,11 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Benutze dein %1$s oder deinen %2$s um fortzufahren. Wiederherstellungsschlüssel verwenden Wähle deinen Wiederherstellungsschüssel, gib ihn ein oder füge ihn aus der Zwischenablage ein + Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden. Bitte stelle sicher, dass du den korrekten Wiederherstellungsschlüssel eingegeben hast. + Konnte nicht auf gesicherten Speicher zugreifen + + Unverschlüsselt + Verschlüsselt von einem unbekannten Gerät + Überprüfe, wo du eingeloggt bist + Bestätige all deine Sitzungen, um sicher zu stellen, dass dein Konto & Nachrichten sicher sind From 22d06928c88247d51bf29c3071642947b5187c16 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:06:48 +0000 Subject: [PATCH 055/199] Translated using Weblate (German) Currently translated at 99.6% (1665 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 6ef0289a21..bd2c3ba0a4 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2429,5 +2429,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Unverschlüsselt Verschlüsselt von einem unbekannten Gerät Überprüfe, wo du eingeloggt bist - Bestätige all deine Sitzungen, um sicher zu stellen, dass dein Konto & Nachrichten sicher sind + Verifiziere alle deine Sitzungen, um sicher zu stellen, dass dein Konto & deine Nachrichten sicher sind From 1785d4d0b4e36c33c447d28587a42bf30a17cb5a Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:07:11 +0000 Subject: [PATCH 056/199] Translated using Weblate (German) Currently translated at 99.6% (1665 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index bd2c3ba0a4..cbab7b4f2c 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2430,4 +2430,10 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verschlüsselt von einem unbekannten Gerät Überprüfe, wo du eingeloggt bist Verifiziere alle deine Sitzungen, um sicher zu stellen, dass dein Konto & deine Nachrichten sicher sind + Bestätige neue Anmeldung für dein Konto: %1$s + + Verifiziere manuell mit einem Text + Verifiziere Anmeldung + Verifiziere interaktiv mit Emojis + Bestätige deine Identität indem du diesen Login von einer deiner anderen Sitzungen verifizierst um Zugriff auf deine verschlüsselten Nachrichten zu erhalten. From 07c625973494a34df18046270b712d78d309b5fb Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:08:11 +0000 Subject: [PATCH 057/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index cbab7b4f2c..2a35f87579 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2435,5 +2435,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verifiziere manuell mit einem Text Verifiziere Anmeldung Verifiziere interaktiv mit Emojis - Bestätige deine Identität indem du diesen Login von einer deiner anderen Sitzungen verifizierst um Zugriff auf deine verschlüsselten Nachrichten zu erhalten. + Bestätige deine Identität, indem du diesen Login von einer deiner anderen Sitzungen verifizierst, um Zugriff auf deine verschlüsselten Nachrichten zu erhalten. From b44b0ec998f46eacb897393ebcdf0c3e41a5f4ac Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Wed, 6 May 2020 22:08:16 +0000 Subject: [PATCH 058/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 2a35f87579..9b720eef4d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2436,4 +2436,14 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verifiziere Anmeldung Verifiziere interaktiv mit Emojis Bestätige deine Identität, indem du diesen Login von einer deiner anderen Sitzungen verifizierst, um Zugriff auf deine verschlüsselten Nachrichten zu erhalten. - + Als vertraut markieren + + Bitte wähle einen Benutzernamen. + Bitte wähle ein Passwort. + Überprüfe diesen Link genau + Dieser Link %1$s bringt dich zu einer anderen Seite: %2$s. +\n +\nWillst du wirklich fortfahren\? + + Konnte Direkt-Nachrichten Raum nicht erzeugen. Prüfe die Nutzer, die du einladen willst und versuche es erneut. + From 0aa90c3eea6ea168a6acc15e922a05a630f963df Mon Sep 17 00:00:00 2001 From: Ville Ranki Date: Thu, 7 May 2020 06:15:01 +0000 Subject: [PATCH 059/199] Translated using Weblate (Finnish) Currently translated at 100.0% (163 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/fi/ --- matrix-sdk-android/src/main/res/values-fi/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml index 9487aa7db4..cdad3f3e41 100644 --- a/matrix-sdk-android/src/main/res/values-fi/strings.xml +++ b/matrix-sdk-android/src/main/res/values-fi/strings.xml @@ -209,4 +209,6 @@ %1$s laittoi päälle osapuolten välisen salauksen. %1$s laittoi päälle osapuolisten välisen salauksen (tuntematon algoritmi %2$s). +%s haluaa vahvistaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten vahvistusta. Joudut käyttämään perinteistä vahvistustapaa avainten vahvistamiseen. + From 44f946513f22b1410427e7cf956fa18cae22d058 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 8 May 2020 06:15:51 +0000 Subject: [PATCH 060/199] Added translation using Weblate (Swedish) --- vector/src/main/res/values-sv/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 vector/src/main/res/values-sv/strings.xml diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/vector/src/main/res/values-sv/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From c2b2b856a1438c6f6a1b00714e51b45f987ac7fe Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 6 May 2020 20:04:35 +0000 Subject: [PATCH 061/199] Translated using Weblate (Albanian) Currently translated at 99.6% (1665 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sq/ --- vector/src/main/res/values-sq/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 10ecd0af4d..7f771a81ea 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -592,7 +592,7 @@ Importo Jepni frazëkalimin Fshehtëzoje vetëm për sesione të verifikuar - Jo i verifikuar + Jo i Verifikuar I verifikuar Në Listë të Zezë @@ -2147,7 +2147,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Mundësi e Përzgjedhur Krijoni një pyetësor të thjeshtë - Përdorni metodë rimarrjesh + Përdorni Frazëkalim Rikthimesh ose Kyç Nëse s’hyni dot në një sesion ekzistues Hyrje e Re @@ -2204,7 +2204,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Verifikoni pajisjet tuaja që prej Rregullimeve. Verifikimi u Anulua - Fjalëkalim Mesazhesh + Frazëkalim Rikthimesh Kyç Mesazhesh Fjalëkalim Llogarie @@ -2278,7 +2278,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Emër përdoruesi dhe/ose fjalëkalim i pasaktë. Fjalëkalimi i dhënë fillon ose mbaron me hapësirë, ju lutemi, kontrollojeni. - + Po publikohen kyçe të krijuar identiteti Mesazh… @@ -2325,7 +2325,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Përdorni Kyçin Rimarrjesh Përzgjidhni Kyçin tuaj të Rimarrjeve, ose jepeni dorazi duke e shtypur ose duke e ngjitur prej të papastrës tuaj Kopjeruajtja s’u shfshehtëzua dot me këtë Kyç Rimarrjesh: ju lutemi, verifikoni se keni dhënë Kyçin e saktë të Rimarrjeve. - S\"u arrit të hyhet në depozitë të sigurt + S’u arrit të hyhet në depozitë të sigurt Të pafshehtëzuara Fshehtëzuar nga një pajisje e paverifikuar @@ -2335,11 +2335,11 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Verifikojeni Dorazi përmes Teksti Verifikoni kredenciale hyrjeje - Verifikojeni përmes Emoji-sh + Verifikojeni Në Mënyrë Interaktive përmes Emoji-sh Ripohoni identitetin tuaj duke verifikuar këto kredenciale hyrjesh prej një nga sesionet tuaj të tjerë, duke i akorduar hyrje te mesazhet e fshehtëzuar. Vërini shenjë si i Besuar - Ju lutemi zgjidhni një emër përdoruesi. + Ju lutemi, zgjidhni një emër përdoruesi. Ju lutemi, zgjidhni një fjalëkalim. Kontrollojeni edhe një herë këtë lidhje Lidhja %1$s po ju shpie te një tjetër sajt: %2$s. From 67d1c2dc801298e18151c993b9b61ed8076c8fbd Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Wed, 6 May 2020 17:31:43 +0000 Subject: [PATCH 062/199] Translated using Weblate (Albanian) Currently translated at 98.8% (161 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/sq/ --- matrix-sdk-android/src/main/res/values-sq/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-sq/strings.xml b/matrix-sdk-android/src/main/res/values-sq/strings.xml index e966f22064..521c805be8 100644 --- a/matrix-sdk-android/src/main/res/values-sq/strings.xml +++ b/matrix-sdk-android/src/main/res/values-sq/strings.xml @@ -4,8 +4,8 @@ %1$s dërgoi një figurë. %1$s ftoi %2$s %1$s ju ftoi - %1$s u bë pjesë - %1$s iku + %1$s hyri në dhomë + %1$s doli nga dhoma %1$s hodhi tej ftesën %1$s përzuri %2$s %1$s dëboi %2$s @@ -172,8 +172,8 @@ Ftesë e %1$s. Arsye: %2$s %1$s ftoi %2$s. Arsye: %3$s %1$s ju ftoi. Arsye: %2$s - %1$s erdhi. Arsye: %2$s - %1$s iku. Arsye: %2$s + %1$s erdhi në dhomë. Arsye: %2$s + %1$s doli nga dhoma. Arsye: %2$s %1$s hodhi poshtë ftesën. Arsye: %2$s %1$s përzuri %2$s. Arsye: %3$s %1$s hoqi dëbimin për %2$s. Arsye: %3$s From f1613eacbb729a0485ea54794e126496d04b5bf8 Mon Sep 17 00:00:00 2001 From: Ville Ranki Date: Thu, 7 May 2020 06:10:18 +0000 Subject: [PATCH 063/199] Translated using Weblate (Finnish) Currently translated at 94.0% (1572 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/fi/ --- vector/src/main/res/values-fi/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index 046508524d..fcd2dcad43 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -2282,4 +2282,10 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Tätä ei pysty tekemään kännykällä + Mukautettu + Mukautettu (%1$d) %2$s:ssä + + Syy poistoon + + Viestin avain From 6c1c1ca8b026712e897683fb317ca5952d2a0592 Mon Sep 17 00:00:00 2001 From: Samu Voutilainen Date: Thu, 7 May 2020 06:15:43 +0000 Subject: [PATCH 064/199] Translated using Weblate (Finnish) Currently translated at 100.0% (163 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/fi/ --- matrix-sdk-android/src/main/res/values-fi/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml index cdad3f3e41..ecb2edd303 100644 --- a/matrix-sdk-android/src/main/res/values-fi/strings.xml +++ b/matrix-sdk-android/src/main/res/values-fi/strings.xml @@ -209,6 +209,6 @@ %1$s laittoi päälle osapuolten välisen salauksen. %1$s laittoi päälle osapuolisten välisen salauksen (tuntematon algoritmi %2$s). -%s haluaa vahvistaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten vahvistusta. Joudut käyttämään perinteistä vahvistustapaa avainten vahvistamiseen. +%s haluaa varmentaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten varmennusta. Joudut käyttämään perinteistä varmennustapaa. From 17db994d35593ffcc5efdf89dcc5a40d8b728069 Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 22:10:26 +0000 Subject: [PATCH 065/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 9b720eef4d..f3663c59af 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2445,5 +2445,5 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine \n \nWillst du wirklich fortfahren\? - Konnte Direkt-Nachrichten Raum nicht erzeugen. Prüfe die Nutzer, die du einladen willst und versuche es erneut. + Konnte Direktnachricht nicht erzeugen. Prüfe die Nutzer, die du einladen willst und versuche es erneut. From 8616c454e1cc58d079da847ad91f487d69d21c0b Mon Sep 17 00:00:00 2001 From: laeberkaes Date: Wed, 6 May 2020 21:10:52 +0000 Subject: [PATCH 066/199] Translated using Weblate (German) Currently translated at 100.0% (163 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/de/ --- matrix-sdk-android/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-de/strings.xml b/matrix-sdk-android/src/main/res/values-de/strings.xml index dc874c2b94..871d01175e 100644 --- a/matrix-sdk-android/src/main/res/values-de/strings.xml +++ b/matrix-sdk-android/src/main/res/values-de/strings.xml @@ -179,8 +179,8 @@ %1$s\'s Einladung. Grund: %2$s %1$s hat %2$s eingeladen. Grund: %3$s %1$s hat dich eingeladen. Grund: %2$s - %1$s beigetreten. Grund: %2$s - %1$s ging. Grund: %2$s + %1$s ist dem Raum beigetreten. Grund: %2$s + %1$s hat den Raum verlassen. Grund: %2$s %1$s hat die Einladung abgelehnt. Grund: %2$s %1$s hat %2$s gekickt. Grund: %3$s %1$s hat Sperre von %2$s aufgehoben. Grund: %3$s From c33f3b76fa3c0e07f74cb652e6527188248a1f06 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 8 May 2020 06:21:21 +0000 Subject: [PATCH 067/199] Translated using Weblate (Swedish) Currently translated at 0.5% (8 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sv/ --- vector/src/main/res/values-sv/strings.xml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index a6b3daec93..dbcb290594 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -1,2 +1,12 @@ - - \ No newline at end of file + +sv + SE + Latn + + Ljust tema + Mörkt tema + Svart tema + Status.im-tema + + Initialiserar tjänsten + From 690d05aeca44d691e9e9a3ef6dd2ec3fd51812c0 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 9 May 2020 10:13:31 +0000 Subject: [PATCH 068/199] Translated using Weblate (Danish) Currently translated at 23.8% (398 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/da/ --- vector/src/main/res/values-da/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-da/strings.xml b/vector/src/main/res/values-da/strings.xml index 62383f40bb..411a8d4099 100644 --- a/vector/src/main/res/values-da/strings.xml +++ b/vector/src/main/res/values-da/strings.xml @@ -378,7 +378,7 @@ Er du sikker? Er du sikker på, at du ønsker at starte en ny chat med %s? Er du sikker på, at du ønsker at starte et opkald? - Er du sikker på, at du ønsker at du ønsker at starte et videoopkald? + Er du sikker på, at du ønsker at starte et videoopkald\? Inviter Liste over grupper From 247ffc12707c84c9b1a7b43d335187f52ede124d Mon Sep 17 00:00:00 2001 From: Tirifto Date: Fri, 8 May 2020 14:33:37 +0000 Subject: [PATCH 069/199] Translated using Weblate (Esperanto) Currently translated at 82.2% (134 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/eo/ --- .../src/main/res/values-eo/strings.xml | 162 +++++++++++++++++- 1 file changed, 154 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-eo/strings.xml b/matrix-sdk-android/src/main/res/values-eo/strings.xml index c88d96d610..32e05589f6 100644 --- a/matrix-sdk-android/src/main/res/values-eo/strings.xml +++ b/matrix-sdk-android/src/main/res/values-eo/strings.xml @@ -3,20 +3,166 @@ %1$s sendis bildon. %1$s sendis glumarkon. - invito de %s - %1$s invitis %2$s + Invito de %s + %1$s invitis uzanton %2$s %1$s invitis vin %1$s alvenis %1$s foriris %1$s malakceptis la inviton - %1$s forpelis %2$s - %1$s malforbaris %2$s - %1$s forbaris %2$s - %1$s malinvitis %2$s + %1$s forpelis uzanton %2$s + %1$s malforbaris uzanton %2$s + %1$s forbaris uzanton %2$s + %1$s nuligis inviton por %2$s %1$s ŝanĝis sian profilbildon ** Ne eblas malĉifri: %s ** La aparato de la sendanto ne sendis al ni la ŝlosilojn por tiu mesaĝo. - Respondanta al + Responde al - +%1$s: %2$s + %1$s ŝanĝis sian vidigan nomon al %2$s + %1$s ŝanĝis sian vidigan nomon de %2$s al %3$s + %1$s forigis sian vidigan nomon (%2$s) + %1$s ŝanĝis la temon al: %2$s + %1$s ŝanĝis nomon de la ĉambro al: %2$s + %s vidvokis. + %s voĉvokis. + %s respondis la vokon. + %s finis la vokon. + %1$s videbligis estontan historion de ĉambro al %2$s + ĉiuj ĉambranoj, ekde iliaj invitoj. + ĉiuj ĉambranoj, ekde iliaj aliĝoj. + ĉiuj ĉambranoj. + ĉiu ajn. + nekonata (%s). + %1$s ŝaltis tutvojan ĉifradon (%2$s) + %s gradaltigis la ĉambron. + + Mesaĝo foriĝis + Mesaĝo foriĝis de %1$s + Mesaĝo foriĝis [kialo: %1$s] + Mesaĝo foriĝis de %1$s [kialo: %2$s] + %1$s ĝisdatigis sian profilon %2$s + %1$s sendis aliĝan inviton al %2$s + %1$s nuligis la aliĝan inviton por %2$s + %1$s akceptis la inviton por %2$s + + Ne povis redakti + Ne povas sendi mesaĝon + + Malsukcesis alŝuti bildon + + Reta eraro + Matrix-eraro + + Nun ne eblas re-aliĝi al malplena ĉambro + + Ĉifrita mesaĝo + + Retpoŝtadreso + Telefonnumero + + sendis bildon. + sendis filmon. + sendis sondosieron. + sendis dosieron. + + Invito de %s + Ĉambra invito + + %1$s kaj %2$s + + + %1$s kaj 1 alia + %1$s kaj %2$d aliaj + + + Malplena ĉambro + + + Hundo + Kato + Leono + Ĉevalo + Unukorno + Porko + Elefanto + Kuniklo + Pando + Koko + Pingveno + Testudo + Fiŝo + Polpo + Papilio + Floro + Arbo + Kakto + Fungo + Globo + Luno + Nubo + Fajro + Banano + Pomo + Frago + Maizo + Pico + Kuko + Koro + Mieneto + Roboto + Ĉapelo + Okulvitroj + Boltilo + Kristnaska viro + Dikfingro supren + Ombrelo + Sablohorloĝo + Horloĝo + Donaco + Lampo + Libro + Grifelo + Paperkuntenilo + Tondilo + Seruro + Ŝlosilo + Martelo + Telefono + Flago + Vagonaro + Biciklo + Aviadilo + Raketo + Trofeo + Pilko + Gitaro + Trumpeto + Sonorilo + Ankro + Kapaŭdilo + Dosierujo + Pinglo + + Komenca spegulado: +\nEnportante konton… + Komenca spegulado: +\nEnportante ĉifrilojn + Komenca spegulado: +\nEnportante ĉambrojn + Komenca spegulado: +\nEnportante aliĝitajn ĉambrojn + Komenca spegulado: +\nEnportante ĉambrojn de invitoj + Komenca spegulado: +\nEnportante forlasitajn ĉambrojn + Komenca spegulado: +\nEnportante komunumojn + Komenca spegulado: +\nEnportante datumojn de konto + + Sendante mesaĝon… + Vakigi sendan atendovicon + + From 9a9f0c200eac379f2a060750d520a8a3cf4ff91e Mon Sep 17 00:00:00 2001 From: Alexander Eisele Date: Fri, 8 May 2020 10:31:56 +0000 Subject: [PATCH 070/199] Translated using Weblate (German) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f3663c59af..f6377e20d7 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -247,9 +247,9 @@ Information Riot benötigt die Berechtigung, auf deine Fotos und Videos zugreifen zu können, um Anhänge zu senden und zu speichern.\n\nBitte erlaube den Zugriff im nächsten Dialog, um Dateien von deinem Gerät zu versenden. Riot benötigt die Berechtigung, auf deine Kamera zugreifen zu können, um Bilder aufzunehmen und Video-Anrufe durchzuführen. - - -Bitte erlaube den Zugriff im nächsten Dialog, um den Anruf zu durchzuführen. + " +\n +\nBitte erlaube den Zugriff im nächsten Dialog, um den Anruf zu durchzuführen." Riot benötigt die Berechtigung, auf dein Mikrofon zugreifen zu können, um (Sprach-)Anrufe tätigen zu können. @@ -768,12 +768,12 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Lädt… Schließen - Communities + Gemeinschaften Community-Namen filtern Einladen - Communities + Gemeinschaften Keine Gruppen Bist du sicher, dass du einen neuen Chat mit %s starten möchtest? @@ -2356,7 +2356,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verschlüsselung ist nicht aktiviert Dies kann nicht von einem mobilen Gerät erfolgen - Wenn sich Raumversionen ändern + Wenn Räume verbessert werden Verschlüsselung aktiviert Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr & verifiziere Benutzer in deren Profil. Die Verschlüsselung in diesem Raum wird nicht unterstützt From d8d78b124deb8aba78ce263e1571fbb920f05c48 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Fri, 8 May 2020 10:32:59 +0000 Subject: [PATCH 071/199] Translated using Weblate (German) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f6377e20d7..9cba959593 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -251,9 +251,9 @@ \n \nBitte erlaube den Zugriff im nächsten Dialog, um den Anruf zu durchzuführen." Riot benötigt die Berechtigung, auf dein Mikrofon zugreifen zu können, um (Sprach-)Anrufe tätigen zu können. - - -Bitte erlaube den Zugriff im nächsten Dialog, um den Anruf durchzuführen. + " +\n +\nBitte erlaube den Zugriff im nächsten Dialog, um den Anruf durchzuführen." Riot benötigt die Berechtigung, auf deine Kamera und dein Mikrofon zugreifen zu können, um Video-Anrufe durchführen zu können. Bitte erlaube den Zugriff im nächsten Dialog, um den Anruf durchzuführen. @@ -646,8 +646,8 @@ Achtung: Diese Datei wird vielleicht gelöscht, wenn die App deinstalliert wird. Zulassen Sitzung verifizieren - Um zu verifizieren, dass dieser Sitzung vertraut werden kann, kontaktiere bitte den/die Eigentümer!n der Sitzung über andere Kommunikationsmittel (z. B. persönlich oder telefonisch) und vergewissere dich, ob der Schüssel, den er/sie in den Benutzereinstellungen für diese Sitzung sieht, mit folgendem übereinstimmt: - Wenn er übereinstimmt, drücke unten den Bestätigen-Button. Stimmt er nicht überein, überwacht jemand anderes diese Sitzung und du solltest ggf. den Blockieren-Button drücken. In Zukunft wird dieser Bestätigungsprozess noch komfortabler gestaltet. + Vergleiche die folgenden Zeichen mit den Einstellungen in der Sitzung des/der anderen Nutzer!n und bestätige: + Falls sie nicht übereinstimmen, wurde die Kommunikation vielleicht kompromittiert. Ich bestätige, dass die Schlüssel übereinstimmen Riot unterstützt jetzt Ende-zu-Ende-Verschlüsselung, du musst dich jedoch erneut anmelden, um sie zu aktivieren. @@ -1302,9 +1302,9 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Sicherung wiederhergestellt %s ! %1$d Sitzungsschlüssel wurde(n) wiederhergestellt und %2$d vorher unbekannte(r) Schlüssel wurde(n) hinzugefügt - Backup mit %d Schlüssel wiederhergestellt. - Backup mit %d Schlüssel wiederhergestellt. - + Backup mit %d Schlüssel wiederhergestellt. + Backup mit %d Schlüsseln wiederhergestellt. + %d neuer Schlüssel wurde dieser Sitzung hinzugefügt. %d neue Schlüssel wurden dieser Sitzung hinzugefügt. From 969f0701756529333317cced1a90faab09ea6b16 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 8 May 2020 06:54:58 +0000 Subject: [PATCH 072/199] Translated using Weblate (Swedish) Currently translated at 10.6% (178 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sv/ --- vector/src/main/res/values-sv/strings.xml | 204 +++++++++++++++++++++- 1 file changed, 203 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index dbcb290594..ef8e94c9e5 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -8,5 +8,207 @@ Svart tema Status.im-tema - Initialiserar tjänsten + Initialiserar tjänst + Synkroniserar… + Lyssnar efter händelser + Högljudda notifikationer + Tysta notifikationer + + Meddelanden + Rum + Inställningar + Medlemsdetaljer + Historisk + Buggrapport + Gemenskapsdetaljer + Skicka ett klistermärke + Säkerhetskopiering av nycklar + Använd säkerhetskopiering av nycklar + Verifiera session + + Säkerhetskopiering av nycklar är inte färdig, vänligen vänta… + Du kommer att förlora dina krypterade meddelanden om du loggar ut nu + Säkerhetskopiering av nycklar pågår. Om du loggar ut nu så kommer du att förlora åtkomst till dina krypterade meddelanden. + Säker säkerhetskopiering av nycklar bör vara aktivt i alla dina sessioner för att förhindra att du förlorar åtkomst till dina krypterade meddelanden. + Jag vill inte ha mina krypterade meddelanden + Säkerhetskopierar nycklar… + Använd säkerhetskopiering av nycklar + Är du säker\? + Säkerhetskopiera + Du kommer att förlora åtkomst till dina krypterade meddelanden om du inte säkerhetskopierar dina nycklar innan du loggar ut. + + Tredjepartslicenser + + Laddar… + + OK + Avbryt + Spara + Lämna + Stanna + Skicka + Kopiera + Skicka igen + Ta bort + Citat + Ladda ner + Dela + Prata + Rensa + Senare + Vidarebefordra + Permanent länk + Visa källa + Visa avkrypterad källa + Radera + Döp om + Ingen + Återkalla + Koppla ifrån + Rapportera innehåll + Aktivt samtal + Pågående gruppsamtal. +\nAnslut som %1$s eller %2$s + Röst + Video + Kan inte starta samtalet, vänligen försök senare + På grund av saknade rättigheter, så kan vissa funktioner saknas… + På grund av saknade rättigheter så kan denna handling inte utföras. + Du behöver ha rätt att bjuda in för att starta ett gruppsamtal i detta rum + Kan inte starta samtal + Sessionsinformation + Gruppsamtal stöds inte i krypterade rum + Ring ändå + Skicka ändå + eller + Bjud in + Bortkopplad + Godkänn + Hoppa över + Färdig + Avbryt + Ignorera + Granska + Avslå + + Avsluta + Handlingar + Logga ut + Är du säker på att du vill logga ut\? + Röstsamtal + Videosamtal + Global sökning + Markera alla som skickade + Historisk + Snabbsvar + Markera som läst + Öppna + Stäng + Kopierat till klippbordet + Stäng av + + Bekräftelse + Varning + Fel + + Hem + Favoriter + Personer + Rum + Gemenskaper + + Filtrera rumsnamn + Filtrera favoriter + Filtrera personer + Filtrera rumsnamn + Filtrera gemenskapsnamn + + Inbjudningar + Låg prioritet + Systemvarningar + + Konversationer + Lokal adressbok + Användarkatalog + Bara Matrix-kontakter + Inga konversationer + Du gav inte Riot tillgång till dina lokala kontakter + Inga resultat + Ingen identitetsserver konfigurerad. + + Rum + Rumskatalog + Inga rum + Inga publika rum tillgängliga + + 1 användare + %d användare + + + Bjud in + Gemenskaper + Inga grupper + + Skicka loggar + Skicka kraschloggar + Skicka skärmdump + Rapportera bugg + Vänligen beskriv buggen. Vad gjorde du\? Vad förväntade du dig skulle hända\? Vad hände istället\? + Om möjligt, skriv vänligen beskrivningen på engelska. + Beskriv ditt problem här + För att diagnostisera problemet kommer loggar från den här klienten att skickas med den här buggrapporten. Denna buggrapport, inklusive loggarna och skärmdumpen, kommer att vara publikt synlig. Om du skulle föredra att endast skicka texten ovan, vänligen avmarkera: + Du verkar skaka din telefon i frustration. Vill du skicka en buggrapport\? + Appen kraschade senaste gången. Vill du skicka en buggrapport\? + Raseriskaka för att rapportera bugg + + Buggrapporten har skickats framgångsrikt + Sändning av buggrapporten misslyckades (%s) + Framsteg (%s%%) + + Skicka in i + Läs + + Gå med i rummet + Användarnamn + Skapa konto + Logga in + Logga ut + URL för hemserver + URL för identitetsserver + Sök + + Starta ny chatt + Starta röstsamtal + Starta videosamtal + + Skicka röst + + Är du säker på att du vill skapa en ny chatt med %s\? + Är du säker på att du vill starta ett röstsamtal\? + Är du säker på att du vill skapa ett videosamtal\? + Samtal misslyckades p.g.a. felkonfigurerad server + Vänligen be administratören för din hemserver (%1$s) att konfigurera en TURN-server för att samtal ska funka pålitligt. +\n +\nAlternativt så kan du försöka använda den publika servern på %2$s, men detta kommer inte att vara lika pålitligt, och kommer att dela din IP-adress med den servern. Du kan också hantera detta i inställningarna. + Försök med %s + Fråga mig inte igen + + Skicka filer + Skicka klistermärke + Ta foto eller video + Ta ett foto + Ta en video + + Du har för närvarande inga klistermärkespaket aktiva. +\n +\nLägg till några nu\? + + fortsätt med… + Tyvärr har ingen extern applikation hittats som kan fullfölja denna handling. + + Logga in + Logga in med externt konto + Skapa konto + Skicka in + Hoppa över From 738a368a6f475a898c2ebcb7d9330275116a96b7 Mon Sep 17 00:00:00 2001 From: kujaw Date: Sat, 9 May 2020 18:02:14 +0000 Subject: [PATCH 073/199] Translated using Weblate (Polish) Currently translated at 93.1% (1557 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/pl/ --- vector/src/main/res/values-pl/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index d36b9570b9..d6b8392744 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2243,4 +2243,6 @@ Spróbuj uruchomić ponownie aplikację. Odblokuj historię zaszyfrowanych wiadomości + " RiotX Android" + From 9124844e3ec19f1f409913f2311e69a2ab67fa87 Mon Sep 17 00:00:00 2001 From: zurtel22 Date: Sun, 10 May 2020 20:54:30 +0000 Subject: [PATCH 074/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 9cba959593..f4bd3a0e7f 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -37,7 +37,7 @@ Sprache Video Das Gespräch kann nicht gestartet werden, bitte später erneut versuchen - Aufgrund fehlender Berechtigungen stehen eventuell einige Funktionen vielleicht nicht zur Verfügung… + Aufgrund fehlender Berechtigungen stehen eventuell manche Funktionen nicht zur Verfügung… Dir fehlt das Recht ein Konferenzgespräch in diesem Raum zu starten Kann Gespräch nicht starten Sitzungsinformationen @@ -768,12 +768,12 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Lädt… Schließen - Gemeinschaften + Communities Community-Namen filtern Einladen - Gemeinschaften + Communities Keine Gruppen Bist du sicher, dass du einen neuen Chat mit %s starten möchtest? @@ -1045,7 +1045,7 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Entschuldige, ein Fehler trat auf Version %s - Status.im-Thema + Status.im Design Bitte eine Passphrase erstellen um exportierte Schlüssel zu verschlüsseln. Du musst dieselbe Passphrase eingeben um die Schlüssel importieren zu können. Erzeuge Passphrase @@ -1212,7 +1212,7 @@ Um sicherzustellen, dass du nichts verpasst, lass deine Updates einfach aktivier Schlüsselsicherung ist nicht abgeschlossen. Bitte warten… Überspringen - Erledigt + Fertig Erweiterte Benachrichtigungseinstellungen Angepasste Einstellungen. From 0eb68b531cffd51e427c3e2c6c9c6cdd61b2030e Mon Sep 17 00:00:00 2001 From: nikonak Date: Sun, 10 May 2020 21:03:48 +0000 Subject: [PATCH 075/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f4bd3a0e7f..e77b587242 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -38,7 +38,7 @@ Video Das Gespräch kann nicht gestartet werden, bitte später erneut versuchen Aufgrund fehlender Berechtigungen stehen eventuell manche Funktionen nicht zur Verfügung… - Dir fehlt das Recht ein Konferenzgespräch in diesem Raum zu starten + Ihnen fehlt das Recht, ein Konferenzgespräch in diesem Raum zu starten Kann Gespräch nicht starten Sitzungsinformationen Konferenzgespräche werden in verschlüsselten Räumen nicht unterstützt @@ -84,7 +84,7 @@ Lokales Adressbuch Nur Matrix-Kontakte Keine Konversationen - Du hast Riot nicht erlaubt auf deine lokalen Kontakte zuzugreifen + Sie haben Riot nicht erlaubt, auf deine lokalen Kontakte zuzugreifen Keine Ergebnisse @@ -982,7 +982,7 @@ Willst du welche hinzufügen? Zeige alle Nachrichten dieses Benutzers? Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen. - Nicht berechtigt diese Aktion durchzuführen. + Nicht berechtigt, diese Aktion durchzuführen. 1s %ds @@ -1330,20 +1330,20 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Um die Schlüsselsicherung für diese Sitzung zu verwenden, stelle sie jetzt mit deiner Passphrase oder deinem Wiederherstellungsschlüssel wieder her. Deine gesicherten Verschlüsselungsschlüssel vom Server löschen\? Du wirst deinen Wiederherstellungsschlüssel nicht mehr nutzen können, um deinen verschlüsselten Chatverlauf zu lesen. - Beim Ausloggen gehen ihre verschlüsselten Nachrichten verloren - Schlüssel-Sicherung wird durchgeführt. Wenn sie sich jetzt ausloggen, dann gehen ihre verschlüsselten Nachrichten verloren. - Schlüssel-Sicherung sollte bei all deinen Sitzungen aktiviert sein um einen Verlust deiner verschlüsselten Nachrichten zu verhindern. + Beim Ausloggen gehen Ihre verschlüsselten Nachrichten verloren + Schlüssel-Sicherung wird durchgeführt. Wenn Sie sich jetzt ausloggen, dann gehen Ihre verschlüsselten Nachrichten verloren. + Schlüssel-Sicherung sollte bei all Ihren Sitzungen aktiviert sein, um einen Verlust Ihrer verschlüsselten Nachrichten zu verhindern. Ich möchte meine verschlüsselten Nachrichten nicht Sichere Schlüssel… Schlüssel-Sicherung verwenden - Bist du sicher\? + Sind Sie sicher\? Sicherung Alle verschlüsselten Nachrichten gehen verloren wenn du dich ausloggst ohne diese vorher zu sichern. Bleiben Abbrechen - Bist du sicher, dass du dich ausloggen möchtest\? + Sind Sie sicher, dass Sie sich ausloggen möchten\? Wiederherstellung verschlüsselter Nachrichten Bitte gib einen Benutzernamen ein. From 98bf02efa91cb45b658d65d17cb73a4622c49713 Mon Sep 17 00:00:00 2001 From: zurtel22 Date: Sun, 10 May 2020 21:47:22 +0000 Subject: [PATCH 076/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index e77b587242..1a0d94011a 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -84,7 +84,7 @@ Lokales Adressbuch Nur Matrix-Kontakte Keine Konversationen - Sie haben Riot nicht erlaubt, auf deine lokalen Kontakte zuzugreifen + Sie haben Riot nicht erlaubt, auf lokale Kontakte zuzugreifen Keine Ergebnisse @@ -124,7 +124,7 @@ Neuen Chat starten Sprachanruf starten - Video-Anruf starten + Videoanruf starten Dateien senden Foto oder Video aufnehmen @@ -952,7 +952,7 @@ Willst du welche hinzufügen? Bitte gib dein Passwort ein. - Wenn möglich, beschreibe bitte in Englisch. + Wenn möglich, schreiben Sie bitte auf Englisch. Sende verschlüsselte Antwort… Sende unverschlüsselte Antwort… Zeige Medien vor dem Senden From 75f84fe1f431023e2a728db0fa8403544074e488 Mon Sep 17 00:00:00 2001 From: nikonak Date: Sun, 10 May 2020 21:49:42 +0000 Subject: [PATCH 077/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 1a0d94011a..6518ff695a 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -101,10 +101,10 @@ Absturzberichte übermitteln Screenshot übermitteln Problem melden - Bitte beschreibe das Problem. Was hast du genau gemacht? Was sollte passieren? Was passierte tatsächlich? + Bitte beschreiben Sie das Problem. Was haben Sie genau gemacht\? Was sollte passieren\? Was passierte tatsächlich\? Problembeschreibung - Um Probleme diagnostizieren zu können, werden Protokolle dieses Clients zusammen mit dem Fehlerbericht übermittelt. Dieser Fehlerbericht wird, wie die Protokolle und Screenshot, nicht öffentlich sichtbar sein. Wenn du nur den oben eingegebenen Text senden möchtest, bitte die nachfolgenden Haken entsprechend entfernen: - Du scheinst dein Telefon frustriert zu schütteln. Möchtest du das Fenster zum Senden eines Fehlerberichts öffnen? + Um Probleme diagnostizieren zu können, werden Protokolle dieses Clients zusammen mit dem Fehlerbericht übermittelt. Dieser Fehlerbericht wird, wie die Protokolle und der Screenshot, nicht öffentlich sichtbar sein. Wenn Sie nur den oben eingegebenen Text senden möchten, bitte die nachfolgenden Haken entsprechend entfernen: + Sie scheinen Ihr Telefon frustriert zu schütteln. Möchten Sie das Fenster zum Senden eines Fehlerberichts öffnen\? Der Fehlerbericht wurde erfolgreich übermittelt Der Fehlerbericht konnte nicht übermittelt werden (%s) Fortschritt (%s%%) @@ -776,9 +776,9 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Communities Keine Gruppen - Bist du sicher, dass du einen neuen Chat mit %s starten möchtest? - Bist du sicher, dass du einen Sprachanruf starten möchtest? - Bist du sicher, dass du einen Videoanruf starten möchtest? + Sind Sie sicher, dass Sie einen neuen Chat mit %s starten möchten\? + Sind Sie sicher, dass Sie einen Sprachanruf starten möchten\? + Sind Sie sicher, dass Sie einen Videoanruf starten möchten\? Gruppenliste @@ -828,7 +828,7 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Flair - Schüttele um einen Fehler zu melden + Schüttele, um einen Fehler zu melden Aktionen Mitglieder auflisten @@ -1708,9 +1708,9 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Konnte keine Verbindung zum Heimserver herstellen Latn - Bitte frage die Administration deines Heimservers (%1$s) um einen TURN-Server einzurichten, damit Anrufe zuverlässig funktionieren. + Bitte bitten Sie den Administrator Ihres Heimservers (%1$s), einen TURN server einzurichten, damit Anrufe zuverlässig funktionieren. \n -\nAlternativ kannst du einen öffentlichen Server auf %2$s nutzen, doch wird das nicht zu zuverlässig sein und es wird deine IP-Adresse mit dem Server geteilt. Du kannst dies auch in den Einstellungen konfigurieren. +\nAlternativ können Sie einen öffentlichen Server auf %2$s nutzen, doch wird das nicht so zuverlässig sein und es wird Ihre IP-Adresse mit dem Server teilen. Sie können dies auch in den Einstellungen konfigurieren. Dies ist keine Adresse eines Matrixservers Kann Home-Server nicht bei dieser URL erreichen. Bitte überprüfen Wir nutzen %s als Assistenten wenn dein Home-Server keinen anbietet (Deine IP-Adresse wird während des Anrufs geteilt) From 431b285806aee32a9edbdd99deec38f403a9367e Mon Sep 17 00:00:00 2001 From: zurtel22 Date: Sun, 10 May 2020 22:20:28 +0000 Subject: [PATCH 078/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 6518ff695a..12fa952933 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1708,9 +1708,9 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Konnte keine Verbindung zum Heimserver herstellen Latn - Bitte bitten Sie den Administrator Ihres Heimservers (%1$s), einen TURN server einzurichten, damit Anrufe zuverlässig funktionieren. + Bitte fragen Sie den Administrator Ihres Home-Servers nach der Einrichtung eines TURN-Servers, damit Anrufe zuverlässig funktionieren. \n -\nAlternativ können Sie einen öffentlichen Server auf %2$s nutzen, doch wird das nicht so zuverlässig sein und es wird Ihre IP-Adresse mit dem Server teilen. Sie können dies auch in den Einstellungen konfigurieren. +\nAlternativ können Sie einen öffentlichen Server auf %2$s nutzen. Dies wird jedoch weniger zuverlässig sein und Ihre IP-Adresse gegenüber diesem Server preisgeben. Sie können dies auch in den Einstellungen anpassen. Dies ist keine Adresse eines Matrixservers Kann Home-Server nicht bei dieser URL erreichen. Bitte überprüfen Wir nutzen %s als Assistenten wenn dein Home-Server keinen anbietet (Deine IP-Adresse wird während des Anrufs geteilt) From 40649e9c3c8455bc6a15324019018300f7136721 Mon Sep 17 00:00:00 2001 From: nikonak Date: Sun, 10 May 2020 22:20:41 +0000 Subject: [PATCH 079/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 12fa952933..e283a6a6d5 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -902,9 +902,7 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Sende einen Sticker Sende Sticker - Du hast aktuell keine Stickerpackete aktiviert. - -Willst du welche hinzufügen? + Sie haben aktuell keine Stickerpackete aktiviert. Wollen Sie welche hinzufügen\? Deaktiviere Account Deaktivere meinen Account @@ -1660,7 +1658,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Kein Integrationsserver konfiguriert. Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen - Versuche es mit %s + Versuchen Sie es mit %s Nicht erneut fragen Richte eine E-Mail für die Kontowiederherstellung ein. Optional, kannst du später einrichten, dass Personen dich über diese Adresse finden. From d0c722eae1ea7637bc8254dfefac2c523a974720 Mon Sep 17 00:00:00 2001 From: "Pepper.Cabbit.Snoopy" Date: Sun, 10 May 2020 09:27:59 +0000 Subject: [PATCH 080/199] Translated using Weblate (Chinese (Simplified)) Currently translated at 64.5% (1078 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/zh_Hans/ --- vector/src/main/res/values-zh-rCN/strings.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 6f6d809624..f460df6d24 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -210,9 +210,7 @@ 此主服务器想确认您不是机器人 一封电子邮件已发送至 %s。点击了其中的链接后,请点击下面。 电子邮箱地址验证失败:请确保您已点击邮件中的链接 - 密码已重设。 - -您已从所有设备注销并且不再接受推送通知。要重新启用通知,请重新在相应设备上登录。 + 密码已重置。 您已从所有设备注销并且不再接受推送通知。要重新启用通知,请重新在相应设备上登录。 原始 %d 秒 @@ -519,7 +517,7 @@ 这只会发生一次。 请谅解由此造成的不便。 已读标签清单 - "发送为 " + 发送为 Riot 需要访问您的通讯录,才能根据电子邮箱地址和手机号码查找其他 Matrix 用户。 请在接下来的弹出窗口中授权允许访问。 @@ -888,7 +886,7 @@ Matrix 中的消息可见性类似于电子邮件。我们忘记您的消息意 已发送密钥共享请求。 已请求 - 请在可解密此消息的设备上启动 Riot,以便其将密钥发送至当前设备。 + 请在其他可解密此消息的设备上启动 Riot,以便其将密钥发送至当前设备。 在此输入… From 82df62a60094d55ed70d845928c0737954d7c792 Mon Sep 17 00:00:00 2001 From: zurtel22 Date: Sun, 10 May 2020 22:23:53 +0000 Subject: [PATCH 081/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index e283a6a6d5..2252cde49d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -150,8 +150,8 @@ Nutzernamen dürfen nur Buchstaben, Nummern, Punkte, Binde- und Unterstriche enthalten Passwort zu kurz (min. 6 Zeichen) Passwort fehlt - Dies sieht nicht nach einer gültigen E-Mail-Adresse aus - Dies sieht nicht nach einer gültigen Telefonnummer aus + Dies scheint keine gültige E-Mail-Adresse zu sein + Dies scheint keine gültige Telefonnummer zu sein Diese E-Mail-Adresse wird bereits verwendet. E-Mail-Adresse fehlt Telefonnummer fehlt @@ -902,7 +902,7 @@ Du kannst sie jetzt aktivieren oder später über das Einstellungsmenü.Sende einen Sticker Sende Sticker - Sie haben aktuell keine Stickerpackete aktiviert. Wollen Sie welche hinzufügen\? + Sie haben aktuell keine Stickerpakete aktiviert. Möchten Sie welche hinzufügen\? Deaktiviere Account Deaktivere meinen Account From 7f55e4fb1e2b332f56030d4c0600545f37e3c907 Mon Sep 17 00:00:00 2001 From: nikonak Date: Sun, 10 May 2020 22:25:11 +0000 Subject: [PATCH 082/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 2252cde49d..8e02f01157 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -136,7 +136,7 @@ Überspringen Rücksetz-E-Mail senden Zur Anmeldemaske zurückkehren - E-Mail oder Nutzername + E-Mail oder Benutzername Passwort Neues Passwort Benutzername @@ -147,7 +147,7 @@ Passwort wiederholen Neues Passwort bestätigen Benutzername und/oder Passwort falsch - Nutzernamen dürfen nur Buchstaben, Nummern, Punkte, Binde- und Unterstriche enthalten + Benutzernamen dürfen nur Buchstaben, Nummern, Punkte, Binde- und Unterstriche enthalten Passwort zu kurz (min. 6 Zeichen) Passwort fehlt Dies scheint keine gültige E-Mail-Adresse zu sein @@ -1396,7 +1396,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Importiere Schlüssel… Ignorieren - Mit single-sign-on anmelden + Mit Single-Sign-On anmelden Diese URL ist nicht erreichbar, bitte prüfen Dein Gerät nutzt eine veraltetes TLS-Sicherheitsprotokoll, das anfällig für Angriffe ist. Zu deiner Sicherheit wirst du nicht in der Lage sein, dich zu verbinden Schicke Nachricht mit Eingabetaste From 7119403cde855fb3775eba8e8312ffa4fb6637f0 Mon Sep 17 00:00:00 2001 From: tctovsli Date: Sat, 9 May 2020 19:15:52 +0000 Subject: [PATCH 083/199] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 34.5% (577 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/nb_NO/ --- vector/src/main/res/values-nb-rNO/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-nb-rNO/strings.xml b/vector/src/main/res/values-nb-rNO/strings.xml index 54cac5a112..86cb713dbb 100644 --- a/vector/src/main/res/values-nb-rNO/strings.xml +++ b/vector/src/main/res/values-nb-rNO/strings.xml @@ -723,4 +723,12 @@ Send inn i Hjemmetjener URL Start ny chat - +Start lydsamtale + Start videosamtale + + Send lydopptak + + Er du sikker på du vil starte en samtale med %s\? + Er du sikker på du vil starte en lydsamtale\? + Er du sikker på du vil starte en videosamtale\? + From 9e29533aad677a317d80ed8f8ea16e0ef88da8ba Mon Sep 17 00:00:00 2001 From: Frisk Date: Sat, 9 May 2020 18:02:25 +0000 Subject: [PATCH 084/199] Translated using Weblate (Polish) Currently translated at 93.3% (1560 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/pl/ --- vector/src/main/res/values-pl/strings.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index d6b8392744..ca0ae9e542 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2243,6 +2243,10 @@ Spróbuj uruchomić ponownie aplikację. Odblokuj historię zaszyfrowanych wiadomości - " RiotX Android" + RiotX Android + Odśwież + + Użyj tej sesji do weryfikacji nowej, nadając jej dostęp do zaszyfrowanych wiadomości. + To nie ja From a98916c9857c9f0da7d7e31b12cba32af17a2f9e Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sun, 10 May 2020 09:07:28 +0000 Subject: [PATCH 085/199] Translated using Weblate (Swedish) Currently translated at 11.1% (186 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sv/ --- vector/src/main/res/values-sv/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index ef8e94c9e5..6ba74af043 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -211,4 +211,12 @@ Skapa konto Skicka in Hoppa över + Skicka e-brev för återställning + Gå tillbaka till inloggningsskärmen + E-postadress eller användarnamn + Lösenord + Nytt lösenord + Användarnamn + Sätt en e-postadress för kontoåterförvärv, och senare för att valfritt vara upptäckbar av folk som som känner dig. + Sätt ett telefonnummer som folk som känner dig kan använda för att hitta dig. From 684972185fa18d28b19242bc46809fac0c2d6d74 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Mon, 11 May 2020 13:49:44 +0000 Subject: [PATCH 086/199] Translated using Weblate (Esperanto) Currently translated at 14.7% (245 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/eo/ --- vector/src/main/res/values-eo/strings.xml | 252 +++++++++++++++++++--- 1 file changed, 225 insertions(+), 27 deletions(-) diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index 8d4f587fc8..a6e7de2020 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -5,23 +5,23 @@ Malhela haŭto Nigra haŭto - Sinkroniganta - Atentanta pri eventoj + Spegulante… + Atentante eventojn Laŭtaj sciigoj Silentaj sciigoj Mesaĝoj - Babilejo + Ĉambro EO Agordoj - Cimraporto - Komunumaj detaloj + Erar-raporto + Detaloj pri komunumo Sendi glumarkon Permesiloj de eksteraj liverantoj - Ŝarganta… + Enlegante… Bone Nuligi @@ -33,7 +33,7 @@ Forigi Citi Elŝuti - Diskonigi + Kunhavigi Paroli Forviŝi Poste @@ -43,40 +43,41 @@ Vidi malĉifritan fonton Forigi Renomi - Membro-Detaloj + Detaloj pri ano Historia Raporti enhavon - Aktiva alvoko - Cimraporto - Daŭranta telekonferenco.\nAliĝi %1$s aŭ %2$s. - voĉe - videe - Ne eblas ekigi la alvokon, bonvolu provi poste - Ne eblas ekigi alvokon - Pro mankantaj permesoj, kelkaj ebloj eble mankos… + Aktiva voko + Raporti eraron + Daŭranta grupa voko. +\nAliĝi kiel %1$s aŭ %2$s. + Voĉe + Vide + Ne eblas ekigi la vokon, bonvolu provi poste + Ne eblas ekigi vokon + Pro mankantaj permesoj, kelkaj funkcioj eble mankos… Pro mankantaj permesoj, tiu ago ne eblas. - Aparata informo + Informoj pri salutaĵo Tamen sendi Inviti - Malinterrete + Eksterrete Eliri Agoj - Telefono - videotelefono + Voĉvoko + Vidvoko Universala serĉo - Tamen alvoki + Tamen voki Rapida respondo Malfermi Fermi Sendi ĉifritan respondon… Sendi respondon (neĉifritan)… Homoj - Babilejoj + Ĉambroj Komunumoj - Filtri nomojn de babilejoj + Filtri nomojn de ĉambroj Filtri homojn Filtri nomojn de babilejoj Homoj @@ -93,9 +94,206 @@ Babilejoj Salti al unua nelegita mesaĝo. - Ŝlosilo-Sekukopio - Usi Ŝlosilo-Sekukopion - Kontroli aparaton + Savkopiado de ŝlosiloj + Uzi savkopiadon de ŝlosiloj + Kontroli salutaĵon Kontroli aparaton - +Latn + + Haŭto de Status.im + + Savkopio de ŝlosiloj ne finiĝis; bonvolu atendi… + Vi perdos viajn ĉifritajn mesaĝojn se vi nun adiaŭos + Savkopio de ŝlosiloj progresas. Se vi nun adiaŭos, vi perdos aliron al viaj ĉifritaj mesaĝoj. + Sekura savkopiado de ŝlosiloj devus esti aktiva en ĉiuj viaj salutaĵoj por eviti perdon de aliro al viaj ĉifritaj mesaĝoj. + Mi ne volas miajn ĉifritajn mesaĝojn + Savkopiante ŝlosilojn… + Uzi savkopiadon de ŝolsiloj + Ĉu vi certas\? + Savkopii + Vi perdos aliron al viaj ĉifritaj mesaĝoj malse vi savkopios viajn ŝlosilojn antaŭ adiaŭo. + + Resti + Neniu + Senvalidigi + Malkonekti + Vi bezonas permeson inviti por komenci grupan vokon en ĉi tiu ĉambro + Grupaj vokoj ne estas subtenataj de ĉifrataj ĉambroj + Akcepti + Preterpasi + Finite + Ĉesigi + Malatenti + Kontroli + Rifuzi + + Adiaŭi + Ĉu vi certe volas adiaŭi\? + Marki ĉion legita + Historia + Marki legita + Kopiiĝis al tondujo + Malŝalti + + Konfirmo + Averto + Eraro + + Hejmo + Elstarigitaj + Filtri elstarigitajn + Filtri nomojn de komunumoj + + Invitoj + Malalta prioritato + Sistemaj avertoj + + Interparoloj + Loka adresaro + Neniuj interparoloj + Vi ne permesis al Riot aliron al viaj lokaj kontaktoj + Neniuj rezultoj + Neniu identiga servilo estas agordita. + + Ĉambroj + Neniuj ĉambroj + Neniuj publikaj ĉambroj disponeblas + + 1 uzanto + %d uzantoj + + + Inviti + Komunumoj + Neniuj grupoj + + Sendi protokolon + Sendi protokolon pri fiasko + Sendi ekrankopion + Bonvolu priskribi la eraron. Kion vi faris\? Kion vi atendis\? Kio tamen vere okazis\? + Se tio eblas, bonvolu priskribi per la angla lingvo. + Priskribu vian problemon ĉi tie + Sukcese sendis la erar-raporton + Malsukcesis sendi la erar-raporton (%s) + Progreso (%s%%) + + Sendi al + Legite + + Aliĝi al ĉambro + Uzantonomo + Krei konton + Saluti + Adiaŭi + URL de hejmservilo + URL de identiga servilo + Serĉi + + Komenci novan babilon + Komenci voĉvokon + Komenci vidvokon + + Sendi voĉon + + Ĉu vi certe volas komenci novan babilon kun %s\? + Ĉu vi certe volas komenci novan voĉvokon kun %s\? + Ĉu vi certe volas komenci novan vidvokon kun %s\? + Voko malsukcesis pro misagordita servilo + Bonvolu peti de la administranto de via hejmservilo (%1$s) agordon de TURN-servilo, por dependebla funkciigo de vokoj. +\n +\nAlternative vi povas provi publikan servilon je %2$s, sed tio ne funkcios same dependeble, kaj montros vian IP-adreson al tiu servilo. Vi ankaŭ povas administri tion en la Agordoj. + Provu uzon de %s + Ne demandi ree + + Sendi dosierojn + Sendi glumarkon + Foti aŭ filmi + Foti + Filmi + + Vi havas neniujn ŝaltitajn glumarkarojn. +\n +\nĈu vi volas iujn aldoni nun\? + + Pluiĝi per… + Pardonu, troviĝis neniu ekstera aplikaĵo por ĉi tiu ago. + + Saluti + Saluti per ununura saluto + Krei konton + Preterpasi + Sendi restarigan retleteron + Reiri al salutejo + Retpoŝtadreso aŭ uzantonomo + Pasvorto + Nova pasvorto + Uzantonomo + Retpoŝtadreso + Retpoŝtadreso (malnepra) + Telefonnumero + Telefonnumero (malnepra) + Ripetu pasvorton + Konfirmu vian novan pasvorton + Malĝusta uzantonomo kaj/aŭ pasvorto + Uzantonomoj povas enhavi nur literojn, ciferojn, punktojn, streketojn, kaj substrekojn + Pasvorto estas tro mallonga (almenaŭ 6 signoj) + Mankas pasvorto + Ĉi tio ne ŝajnas esti valida retpoŝtadreso + Ĉi tio ne ŝajnas esti valida telefonnumero + Ĉi tiu retpoŝtadreso jam estas difinita + Mankas retpoŝtadreso + Mankas telefonnumero + Mankas retpoŝtadreso aŭ telefonnumero + Pasvortoj ne akordas + Ĉu vi forgesis pasvorton\? + Uzi proprajn agordojn pri servilo (altnivela) + Bonvolu kontroli vian retpoŝton por daŭrigi la registriĝon + Registriĝo per retpoŝtadreso kaj telefonnumero samtempe ankoraŭ ne estas subtenata, ĝis la «API» ekekzistos. Nur la telefonnumero estos konsiderata. +\n +\nVi povas aldoni vian retpoŝtadreson al via profilo en agordoj. + Ĉi tiu hejmservilo volas certiĝi, ke vi ne estas roboto + Uzantonomo jam uziĝas + Hejmservilo: + Identiga servilo: + Mi kontrolis mian retpoŝtadreson + Por restarigi vian pasvorton, enigu la retpoŝtadreson ligitan al via konto: + Necesas enigi la retpoŝtadreson ligitan al via konto. + Necesas enigi novan pasvorton. + Retletero sendiĝis al %s. Vizitinte la enhavitan ligilon, klaku sube. + Malsukcesis kontroli retpoŝtadreson: certiĝu, ke vi klakis la ligilon en la retletero + Via pasvorto restariĝis. +\n +\nVi adiaŭis ĉiujn viajn salutaĵojn kaj ne plu ricevos pasivajn sciigojn. Por reŝalti sciigojn, resalutu ĉiun vian aparaton. + Bonvolu tralegi kaj akcepti la politikojn de ĉi tiu hejmservilo: + + URL komenciĝu per http[s]:// + Ne povas asluti: reta eraro + Ne povas saluti + Ne povas registriĝi: reta eraro + Ne povas registriĝi + Ne povas registriĝi: fiasko pri posedo de retpoŝtadreso + Nevalida uzantonomo/pasvorto + Listo de legokonfirmoj + + Listo de grupoj + + Sendi en formato + Originala + Granda + Meza + Malgranda + + Ĉu nuligi la elŝuton\? + Ĉu nuligi la alŝuton\? + %d s + %1$dm %2$ds + + Hieraŭ + Hodiaŭ + + Nomo de ĉambro + Temo de ĉambro + + Vokoj + From df762e40bb5c97a385f831543c71828d41169732 Mon Sep 17 00:00:00 2001 From: Tirifto Date: Mon, 11 May 2020 12:24:27 +0000 Subject: [PATCH 087/199] Translated using Weblate (Esperanto) Currently translated at 100.0% (163 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/eo/ --- .../src/main/res/values-eo/strings.xml | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/res/values-eo/strings.xml b/matrix-sdk-android/src/main/res/values-eo/strings.xml index 32e05589f6..db73db86e2 100644 --- a/matrix-sdk-android/src/main/res/values-eo/strings.xml +++ b/matrix-sdk-android/src/main/res/values-eo/strings.xml @@ -165,4 +165,48 @@ Sendante mesaĝon… Vakigi sendan atendovicon - + %1$s petis grupan vokon + Grupa voko komenciĝis + Grupa voko finiĝis + + (ankaŭ profilbildo ŝanĝiĝis) + %1$s forigis nomon de la ĉambro + %1$s forigis temon de la ĉambro + Invito de %1$s. Kialo: %2$s + %1$s invitis uzanton %2$s. Kialo: %3$s + %1$s invitis vin. Kialo: %2$s + %1$s aliĝis al la ĉambro. Kialo: %2$s + %1$s foriris de la ĉambro. Kialo: %2$s + %1$s rifuzis la inviton. Kialo: %2$s + %1$s forpelis uzanton %2$s. Kialo: %3$s + %1$s malforbaris uzanton %2$s. Kialo: %3$s + %1$s forbaris uzanton %2$s. Kialo: %3$s + %1$s sendis inviton al la ĉambro al %2$s. Kialo: %3$s + %1$s nuligis la inviton al la ĉambro al %2$s. Kialo: %3$s + %1$s akceptis la inviton por %2$s. Kialo: %3$s + %1$s nuligis la inviton al %2$s. Kialo: %3$s + + + %1$s aldonis %2$s kiel adreson por ĉi tiu ĉambro. + %1$s aldonis %2$s kiel adresojn por ĉi tiu ĉambro. + + + + %1$s forigis %2$s kiel adreson por ĉi tiu ĉambro. + %1$s forigis %2$s kiel adresojn por ĉi tiu ĉambro. + + + %1$s aldonis %2$s kaj forigis %3$s kiel adresojn por ĉi tiu ĉambro. + + %1$s agordis la ĉefadreson por ĉi tiu ĉambro al %2$s. + %1$s forigis la ĉefadreson de ĉi tiu ĉambro. + + %1$s permesis al gastoj aliĝi al la ĉambro. + %1$s malpermesis al gastoj aliĝi al la ĉambro. + + %1$s ŝaltis tutvojan ĉifradon. + %1$s ŝaltis tutvojan ĉifradon (kun nerekonita algoritmo %2$s). + + %s petas kontrolon de via ŝlosilo, sed via kliento ne subtenas kontrolon de ŝlosiloj en la babilujo. Vi devos uzi malnovecan kontrolon de ŝlosiloj. + + From 14b1b105562c15db5a3761b2bae52e66d69c1e57 Mon Sep 17 00:00:00 2001 From: HaHaNoname Date: Mon, 11 May 2020 11:40:00 +0000 Subject: [PATCH 088/199] Translated using Weblate (Russian) Currently translated at 75.2% (1258 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/ru/ --- vector/src/main/res/values-ru/strings.xml | 35 ++++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 014a8ae65c..9028a80a71 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -96,7 +96,7 @@ %d пользователь %d пользователя %d пользователей - + Отправить логи @@ -838,13 +838,13 @@ %d комната %d комнаты %d комнат - + %d комната %d комнаты %d комнат - + %1$s в %2$s @@ -852,7 +852,7 @@ %d активный виджет %d активных виджета %d активных виджетов - + @@ -862,45 +862,45 @@ %d активный участник %d активных участника %d активных участников - + %d участник %d участника %d участников - + %d новое сообщение %d новых сообщения %d новых сообщений - + %1$s комната найдена для %2$s %1$s комнаты найдено для %2$s %1$s комнат найдено для %2$s - + %d изменение членства %d изменения членства %d изменений членства - + %d непрочитанное уведомление %d непрочитанных уведомления %d непрочитанных уведомлений - + %d непрочитанное уведомление %d непрочитанных уведомления %d непрочитанных уведомлений - + Получить аватар Заметка аватара @@ -1038,20 +1038,20 @@ %d выбран %d выбрано %d выбраны - + %d участник %d участника %d участников - + %d комната %d комнаты %d комнат - + Системные оповещения @@ -1339,7 +1339,7 @@ %d новый ключ был добавлен к этому устройству. %d новых ключа были добавлены к этому устройству. %d новых ключей были добавлены к этому устройству. - + @@ -1391,7 +1391,7 @@ Резервное копирование %d ключа… Резервное копирование %d ключей… Резервное копирование %d ключей… - + Все ключи сохранены @@ -1847,4 +1847,5 @@ Подробные логи помогут разработчикам, предоставив больше информации, когда вы отправляете RageShake. Даже когда они разрешены, приложение не логирует ваши сообщения и другие приватные данные. - +Закройте меню создания комнаты… + From 040deea65599819fbcaf2ce7e6343c088a6fc165 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 13 May 2020 16:46:36 +0200 Subject: [PATCH 089/199] Fix crash on restore backup from ky --- CHANGES.md | 1 + .../keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 803b974413..836ecdfaf9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Bugfix 🐛: - Fix | Verify Manually by Text crashes if private SSK not known (#1337) - Sometimes the same device appears twice in the list of devices of a user (#1329) - Random Crashes while doing sth with cross signing keys (#1364) + - Crash | crash while restoring key backup (#1366) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt index c8406570d3..faada7ba3e 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyViewModel.kt @@ -51,7 +51,7 @@ class KeysBackupRestoreFromKeyViewModel @Inject constructor( try { sharedViewModel.recoverUsingBackupPass(recoveryKey) } catch (failure: Throwable) { - recoveryCodeErrorText.value = stringProvider.getString(R.string.keys_backup_recovery_code_error_decrypt) + recoveryCodeErrorText.postValue(stringProvider.getString(R.string.keys_backup_recovery_code_error_decrypt)) } } } From aad4b3dc39d547301ccbd54b07b757c9ca4c5653 Mon Sep 17 00:00:00 2001 From: Dominik Mahnkopf Date: Wed, 13 May 2020 18:51:35 +0000 Subject: [PATCH 090/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 8e02f01157..23ea722c48 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -633,7 +633,7 @@ Achtung: Diese Datei wird vielleicht gelöscht, wenn die App deinstalliert wird. Nur zu verifizierten Sitzungen verschlüsseln Von dieser Sitzung aus keine verschlüsselten Nachrichten an nicht-verifizierte Sitzungen senden. - NICHT verifiziert + Nicht verifiziert Verifiziert Auf der Blockierliste @@ -1043,7 +1043,7 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Entschuldige, ein Fehler trat auf Version %s - Status.im Design + Status.im-Design Bitte eine Passphrase erstellen um exportierte Schlüssel zu verschlüsseln. Du musst dieselbe Passphrase eingeben um die Schlüssel importieren zu können. Erzeuge Passphrase From 0144764f69444ec4a99d9f48d1d06cd515fb172f Mon Sep 17 00:00:00 2001 From: nikonak Date: Wed, 13 May 2020 18:58:38 +0000 Subject: [PATCH 091/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 23ea722c48..0c04342504 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1244,7 +1244,7 @@ Um sicherzustellen, dass du nichts verpasst, lass deine Updates einfach aktivier Wiederherstellungsschlüssel Unerwarteter Fehler Sicherung gestartet - Bist du sicher? + Sind Sie sicher\? Wiederherstellungsschlüssel eingeben Nachrichtenwiederherstellung @@ -1282,7 +1282,7 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Deine Verschlüsselungsschlüssel werden nun im Hintergrund auf deinem Heimserver gesichert. Die initiale Sicherung kann mehrere Minuten dauern. - Du kannst den Zugang zu deinen Nachrichten verlieren, wenn du dich abmeldest oder das Gerät verlierst. + Sie können den Zugang zu Ihren Nachrichten verlieren wenn Sie sich abmeldest oder das Gerät verlieren. Rufe Backupversion ab… Nutze deine Wiederherstellungspassphrase um deinen sicheren Chatverlauf zu entschlüsseln From 0d2acec73e406c5b12a2f1ca4098c5f03b64d21d Mon Sep 17 00:00:00 2001 From: Dominik Mahnkopf Date: Wed, 13 May 2020 19:34:47 +0000 Subject: [PATCH 092/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 0c04342504..6c15d204b9 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1282,14 +1282,14 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Deine Verschlüsselungsschlüssel werden nun im Hintergrund auf deinem Heimserver gesichert. Die initiale Sicherung kann mehrere Minuten dauern. - Sie können den Zugang zu Ihren Nachrichten verlieren wenn Sie sich abmeldest oder das Gerät verlieren. + Sie verlieren möglicherweise den Zugang zu Ihren Nachrichten, wenn Sie sich abmelden oder das Gerät verlieren. - Rufe Backupversion ab… - Nutze deine Wiederherstellungspassphrase um deinen sicheren Chatverlauf zu entschlüsseln - nutze deinen Wiederherstellungsschlüssel + Rufe Backup-Version ab… + Nutzen Sie Ihre Wiederherstellungspassphrase, um Ihren verschlüsselten Chatverlauf lesen zu können + nutzen Sie Ihren Wiederherstellungsschlüssel Wen du deine Wiederherstellungspassphrase nicht weißt, kannst du %s. - Nutze deinen Wiederherstellungsschlüssel um deinen verschlüsselten Chatverlauf zu entschlüsseln + Nutzen Sie Ihren Wiederherstellungsschlüssel, um Ihren verschlüsselten Chatverlauf lesen zu können Wiederherstellungsschlüssel verloren\? Du kannst einen neuen in den Einstellungen einrichten. Sicherung konnte mit dieser Passphrase nicht entschlüsselt werden. Bitte stelle sicher, dass du die korrekte Wiederherstellungspassphrase eingegeben hast. Netzwerkfehler: Bitte überprüfe deine Verbindung und versuche es erneut. @@ -2313,7 +2313,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Dies könnte einige Sekunden dauern, gedulde dich bitte. Wiederherstellung einrichten. Dein Wiederherstellungsschlüssel - Du bist fertig! + Geschafft! Bewahre es sicher auf Abschließen @@ -2359,7 +2359,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr & verifiziere Benutzer in deren Profil. Die Verschlüsselung in diesem Raum wird nicht unterstützt - Warte auf %s... + Warte auf %s… %s setzen Fehlerbehebung @@ -2372,7 +2372,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verifiziere dich & andere, um eure Chats zu schützen - Gebe deinen %s ein um fortzufahren. + Geben Sie zum Fortfahren Ihren %s ein Datei benutzen Dies ist kein gültiger Wiederherstellungsschlüssel From ce304ace2bc6fdb088ff5da7cafd4bb2827cb242 Mon Sep 17 00:00:00 2001 From: nikonak Date: Wed, 13 May 2020 19:44:05 +0000 Subject: [PATCH 093/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 6c15d204b9..8d0c76218a 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -37,7 +37,7 @@ Sprache Video Das Gespräch kann nicht gestartet werden, bitte später erneut versuchen - Aufgrund fehlender Berechtigungen stehen eventuell manche Funktionen nicht zur Verfügung… + Aufgrund fehlender Berechtigungen stehen einige Funktionen eventuell nicht zur Verfügung Ihnen fehlt das Recht, ein Konferenzgespräch in diesem Raum zu starten Kann Gespräch nicht starten Sitzungsinformationen @@ -1287,15 +1287,15 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Rufe Backup-Version ab… Nutzen Sie Ihre Wiederherstellungspassphrase, um Ihren verschlüsselten Chatverlauf lesen zu können nutzen Sie Ihren Wiederherstellungsschlüssel - Wen du deine Wiederherstellungspassphrase nicht weißt, kannst du %s. + Wenn Sie Ihre Wiederherstellungspassphrase nicht wissen, können Sie %s. Nutzen Sie Ihren Wiederherstellungsschlüssel, um Ihren verschlüsselten Chatverlauf lesen zu können - Wiederherstellungsschlüssel verloren\? Du kannst einen neuen in den Einstellungen einrichten. - Sicherung konnte mit dieser Passphrase nicht entschlüsselt werden. Bitte stelle sicher, dass du die korrekte Wiederherstellungspassphrase eingegeben hast. - Netzwerkfehler: Bitte überprüfe deine Verbindung und versuche es erneut. + Haben Sie Ihren Wiederherstellungsschlüssel verloren\? Sie können einen neuen in den Einstellungen einrichten. + Sicherung konnte mit dieser Passphrase nicht entschlüsselt werden. Bitte stellen Sie sicher, dass Sie die korrekte Wiederherstellungspassphrase eingegeben haben. + Netzwerkfehler: Bitte überprüfen Sie Ihre Verbindung und versuchen Sie es erneut. - Bitte gib deinen Wiederherstellungsschlüssel ein - Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden. Bitte stelle sicher, dass du den korrekten Wiederherstellungsschlüssel eingegeben hast. + Bitte geben Sie Ihren Wiederherstellungsschlüssel ein + Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden. Bitte stellen Sie sicher, dass Sie den korrekten Wiederherstellungsschlüssel eingegeben haben. Sicherung wiederhergestellt %s ! %1$d Sitzungsschlüssel wurde(n) wiederhergestellt und %2$d vorher unbekannte(r) Schlüssel wurde(n) hinzugefügt From ebdf75091a72011ddb238c96671cd9cc77805119 Mon Sep 17 00:00:00 2001 From: Dominik Mahnkopf Date: Wed, 13 May 2020 20:24:09 +0000 Subject: [PATCH 094/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 8d0c76218a..eef29e8ab1 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -37,7 +37,7 @@ Sprache Video Das Gespräch kann nicht gestartet werden, bitte später erneut versuchen - Aufgrund fehlender Berechtigungen stehen einige Funktionen eventuell nicht zur Verfügung + Aufgrund fehlender Berechtigungen stehen einige Funktionen eventuell nicht zur Verfügung… Ihnen fehlt das Recht, ein Konferenzgespräch in diesem Raum zu starten Kann Gespräch nicht starten Sitzungsinformationen From 84f2fc41b3cf18349e9f5ac7714783112637f50a Mon Sep 17 00:00:00 2001 From: nikonak Date: Wed, 13 May 2020 20:46:28 +0000 Subject: [PATCH 095/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index eef29e8ab1..988eaaebcf 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1336,7 +1336,7 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Schlüssel-Sicherung verwenden Sind Sie sicher\? Sicherung - Alle verschlüsselten Nachrichten gehen verloren wenn du dich ausloggst ohne diese vorher zu sichern. + Alle verschlüsselten Nachrichten gehen verloren wenn Sie sich ausloggen, ohne diese vorher zu sichern. Bleiben Abbrechen From 37392b5495dfa2eb93994428a622df1ac04f5c38 Mon Sep 17 00:00:00 2001 From: tleydxdy Date: Tue, 12 May 2020 22:59:31 +0000 Subject: [PATCH 096/199] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (163 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/zh_Hans/ --- matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml index 38affc0599..cdd9c5eb8d 100644 --- a/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml +++ b/matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml @@ -5,8 +5,8 @@ %s 的邀请 %1$s 邀请了 %2$s %1$s 邀请了您 - %1$s 加入了 - %1$s 离开了 + %1$s 加入了聊天室 + %1$s 离开了聊天室 %1$s 拒绝了邀请 %1$s 移除了 %2$s %1$s 解封了 %2$s @@ -173,8 +173,8 @@ %1$s 的邀请。理由:%2$s %1$s 邀请了 %2$s。理由:%3$s %1$s 邀请了您。理由:%2$s - %1$s 已加入。理由:%2$s - %1$s 已离开。理由:%2$s + %1$s 加入了聊天室。理由:%2$s + %1$s 离开了聊天室。理由:%2$s %1$s 已拒绝邀请。理由:%2$s %1$s 踢走了 %2$s。理由:%3$s %1$s 取消封锁了 %2$s。理由:%3$s From 36b1717fc1eae0698baebbf2445ec8876c15d094 Mon Sep 17 00:00:00 2001 From: Dominik Mahnkopf Date: Wed, 13 May 2020 20:32:50 +0000 Subject: [PATCH 097/199] Translated using Weblate (Dutch) Currently translated at 68.4% (1144 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/nl/ --- vector/src/main/res/values-nl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index d9156a9efe..8880cd2b5e 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -1616,7 +1616,7 @@ Beantwoorden Opnieuw proberen - Betreed een kamer om de applicatie te gebruiken + Betreed een kamer om de applicatie te gebruiken. Heeft je een uitnodiging gestuurd Uitgenodigd door %s From 0e5f741b6bde3222b9688c6363ec4534ecdcaf7d Mon Sep 17 00:00:00 2001 From: Tirifto Date: Tue, 12 May 2020 18:23:55 +0000 Subject: [PATCH 098/199] Translated using Weblate (Esperanto) Currently translated at 21.2% (355 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/eo/ --- vector/src/main/res/values-eo/strings.xml | 145 +++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index a6e7de2020..2a2aceb733 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -296,4 +296,147 @@ Temo de ĉambro Vokoj - + Pravalorigante servon + + 1 elektita + %d elektitaj + + Misformita identigilo. Ĝi devus esti retpoŝtadreso aŭ identigilo de Matrix, kiel «@lokaparto:mallokaparto» + INVITITA + ALIĜINTA + + Kialo pro raporto de ĉi tiu enhavo + Ĉu vi volas kaŝi ĉiujn mesaĝojn de ĉi tiu uzanto\? +\n +\nRimarku, ke tia ago reekigos la aplikaĵon kaj eble daŭros iom da tempo. + Nuligi alŝuton + Nuligi elŝuton + + Serĉi + Filtri ĉambranojn + Neniuj rezultoj + ĈAMBROJ + MESAĜOJ + ELSTARIGITAJ + ĈAMBROJ + INVITOJ + Komenci babilon + Krei ĉambron + Aliĝi al ĉambro + Aliĝi al ĉambro + + 1 ĉambro + %d ĉambroj + + Ĉiuj mesaĝoj + Nur mencioj + Silentigi + Elstarigi + Forgesi + Mesaĝoj + Agordoj + Versio + Versio %s + Kiam mi estas invitita al ĉambro + Invitoj al vokoj + Mesaĝoj senditaj de roboto + + Fona spegulado + Reĝimo de fona spegulado (eksperimenta) + Optimumigita por baterio + Riot spegulos fone, per maniero konservanta la limigitajn rimedojn de la aparato (ĉefe la baterion). +\nDepende de la stato de la rimedoj de via aparato, la spegulado povus esti prokrastita de la operaciumo. + Optimumigita por tujeco + Riot spegulos fone, ripete, je preciza tempo (agordebla). +\nĈi tio influos uzadon de baterio kaj radiilo, kaj aperigos ĉiaman sciigon pri tio, ke Riot aŭskultas okazojn. + Neniu fona spegulado + Vi sciiĝos pri envenaj mesaĝoj dum la aplikaĵo estas fone. + Malsukcesis ĝisdatigi agordojn. + + + Ruliĝi je eko de sistemo + Ŝalti fonan speguladon + Tempolimo de petoj por spegulado + Preferata intertempo de spegulado + %s +\nLa spegulado povas esti prokrastita, depende de la rimedoj (baterio) aŭ la stato de la aparato (dormeto). + Prokrasto inter ĉiu spegulado + sekundo + sekundoj + + Versio + Versio de olm + Uzokondiĉoj + Kopirajto + Privateca politiko + Vakigi kaŝmemoron + Vakigi kaŝmemoron de vidaŭdaĵoj + + Agordoj de uzanto + Sciigoj + Malatentataj uzantoj + Aliaj + Altnivelaj + Kunigoj + Uzu kunigilon por administri robotojn, pontojn, fenestraĵojn kaj glumarkarojn. +\nKunigiloj ricevas datumojn pri agordoj kaj povas modifi fenestraĵojn, sendi invitojn al ĉambroj, kaj agordi povnivelojn laŭ via rajtigo. + Ĉifroteĥnikaro + Administrado de ĉifraj ŝlasiloj + Celoj de sciigoj + Lokaj kontaktoj + Salutaĵoj + Sendi sciigojn pri tajpado + MarkDown-formatado + Formati mesaĝojn per la sintakso de MarkDown antaŭ sendo. Tio ebligas altnivelan formatadon, ekzemple uzon de steletoj por montri kursivan tekston. + Averto! + Grupa vokado ankoraŭ estas programata kaj eble ne estos dependebla. + + MarkDown ŝaltiĝis. + MarkDown malŝaltiĝis. + + Silente + Laŭte + + Ĉifrita mesaĝo + + Krei + Krei komunumon + Nomo de komunumo + Ekzemplo + Identigilo de komunumo + ekzemplo + + Hejmo + Aliĝintaj + Invititaj + Registriĝi + Saluti + Pluiĝi per ununura saluto + + Via pasvorto estas restarigita. + Vi adiaŭis ĉiujn viajn salutaĵojn kaj ne plu ricevados pasivajn sciigojn. Por reŝalti sciigojn, resalutu per ĉiu via aparato. + Reen al salutejo + + Averto + Via pasvorto ankoraŭ ne ŝanĝiĝis. +\n +\nĈu haltigi la ŝanĝan procedon\? + + Agordi retpoŝtadreson + Neĉifrita + Ĉifrita de nekonata aparato + Mane kontroli per teksto + Kontroli saluton + Interage kontroli per bildsignoj + Konfirmu vian identecon per kontrolo de ĉi tiu saluto el unu el viaj aliaj salutaĵoj, donante al ĝi aliron al viaj ĉifritaj mesaĝoj. + Marki fidata + + Bonvolu elekti uzantonomon. + Bonvolu elekti pasvorton. + Bone kontrolu ĉi tiun ligilon + La ligilo %1$s kondukas vin al alia retejo: %2$s. +\n +\nĈu vi certe volas daŭrigi\? + + Ni ne povis krei vian rektan babilon. Bonvolu kontroli la invitotajn uzantojn kaj reprovi. + From 878e093b6b1c682e1e2a5921fa6da9c697cef804 Mon Sep 17 00:00:00 2001 From: Dominik Mahnkopf Date: Wed, 13 May 2020 20:46:48 +0000 Subject: [PATCH 099/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 988eaaebcf..ca599663a1 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1336,7 +1336,7 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Schlüssel-Sicherung verwenden Sind Sie sicher\? Sicherung - Alle verschlüsselten Nachrichten gehen verloren wenn Sie sich ausloggen, ohne diese vorher zu sichern. + Alle verschlüsselten Nachrichten gehen verloren, wenn Sie sich ausloggen, ohne diese vorher zu sichern. Bleiben Abbrechen From 535148e68af9d89900720e7507d8c4e6b30d211f Mon Sep 17 00:00:00 2001 From: zurtel22 Date: Wed, 13 May 2020 20:47:17 +0000 Subject: [PATCH 100/199] Translated using Weblate (German) Currently translated at 99.9% (1671 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/de/ --- vector/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index ca599663a1..8cb293fc1b 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -38,7 +38,7 @@ Video Das Gespräch kann nicht gestartet werden, bitte später erneut versuchen Aufgrund fehlender Berechtigungen stehen einige Funktionen eventuell nicht zur Verfügung… - Ihnen fehlt das Recht, ein Konferenzgespräch in diesem Raum zu starten + Ihnen fehlt die Berechtigung, ein Konferenzgespräch in diesem Raum zu starten Kann Gespräch nicht starten Sitzungsinformationen Konferenzgespräche werden in verschlüsselten Räumen nicht unterstützt From 0f22b55786f586132dec3a0ea53399d0143c1563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BC=D1=91=D0=B1=D0=B0?= Date: Tue, 12 May 2020 16:29:55 +0000 Subject: [PATCH 101/199] Translated using Weblate (Russian) Currently translated at 82.5% (1380 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/ru/ --- vector/src/main/res/values-ru/strings.xml | 219 +++++++++++++++++++--- 1 file changed, 196 insertions(+), 23 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 9028a80a71..654b12c712 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -21,11 +21,11 @@ Копировать Повторить отправку Удалить - Цитата + Цитировать Поделиться Позже Переслать - Постоянная ссылка + Копировать ссылку Просмотр исходного кода Просмотр расшифрованного исходного кода Удалить @@ -80,7 +80,7 @@ Маловажные - Диалоги + Беседы Локальные контакты Только Matrix контакты Нет диалогов @@ -116,7 +116,7 @@ Прочитан Войти в Комнату - Логин + Имя пользователя Создать аккаунт Войти Выйти @@ -145,7 +145,7 @@ Адрес электронной почты Адрес электронной почты (не обязательно) Номер телефона - Номер телефона (дополнительный) + Номер телефона (по желанию) Повтор пароля Подтвердите ваш новый пароль Неверный логин и/или пароль @@ -208,7 +208,7 @@ Оригинал Крупный Средний - Маленький + Мелкий "Отменить загрузку? @@ -290,7 +290,7 @@ 1 пользователь - Покинуть чат + Покинуть комнату Вы уверены, что хотите покинуть чат? Вы уверены, что хотите исключить %s из чата? Создать @@ -460,7 +460,7 @@ Параметры пользователя Уведомления Игнорируемые - Другое + Другой Дополнительно Криптография Отправлять уведомления на @@ -703,8 +703,8 @@ Сохранить медиа Светлая тема - Темная тема - Черная тема + Тёмная тема + Чёрная тема Звук уведомлений Показывать метки времени в 12-часовом формате @@ -1245,7 +1245,7 @@ Резервное копирование ключей не завершено, пожалуйста, подождите… Пропустить - Skip + Готово Расширенные настройки уведомлений Установка важности уведомления по событию, Настроить звук, светодиод, вибрацию @@ -1364,7 +1364,7 @@ [%1$s] Эта ошибка вне контроля Riot. Причины могут быть разными. Возможно, это будет работать, если вы повторите попытку позже, вы также можете проверить, что службы Google Play не ограничены в использовании данных в настройках системы, или что часы вашего устройства установлены правильно, или это может произойти на модифицированных прошивках. [%1$s] Эта ошибка вне контроля Riot, и, по словам Google, эта ошибка означает, что на устройстве слишком много приложений, зарегистрированных в FCM. Ошибка возникает только в тех случаях, когда существует огромное количество приложений, поэтому она не должна влиять на обычного пользователя. - Ваши зашифрованные сообщения будут потеряны если выйдете сейчас + Ваши зашифрованные сообщения будут потеряны, если выйдете сейчас Выполняется резервное копирование ключа. Если выйти сейчас, Вы потеряете доступ к Вашим зашифрованным сообщениям. Мне не нужны мои зашифрованные сообщения Выполняется резервное копирование ключей… @@ -1550,7 +1550,7 @@ Вы вышли из системы из-за недействительных или истекших учетных данных. Редактировать - Ответ + Ответить Повторить Присоединитесь к комнате, чтобы начать использовать приложение. @@ -1566,19 +1566,19 @@ Комнаты Ваши комнаты будут отображаться здесь - Реакция - Соглашаться + Отсебятины + Принять Нравиться - Добавить действие - Посмотреть реакции + Добавить отсебятину + Просмотреть отсебятины Менеджер интеграции Менеджер интеграции не настроен. - Реакции + Отсебятины - Удаленное пользователем событие + Событие удалено пользователем Мероприятие, модерируемое администратором помещения - Последний раз редактировался %1$s на %2$s + Последний раз редактировалось %1$s на %2$s Некорректное событие, не может быть отображено @@ -1591,7 +1591,7 @@ Эту комнату нельзя предварительно просмотреть Комнаты - Прямые сообщения + Личная переписка Новая комната СОЗДАТЬ @@ -1656,7 +1656,7 @@ Предварительный просмотр открытой комнаты в RiotX пока не поддерживается - Прямые сообщения + Личная переписка Ждите… Шифрование миниатюры… @@ -1839,7 +1839,7 @@ Заблокировать пользователя Все сообщения - Только упоминания + Только при упоминаниях Настройки Покинуть комнату %1$s сделал комнату доступной для всех, у кого есть ссылка. @@ -1848,4 +1848,177 @@ Закройте меню создания комнаты… + Вниз + + Контакт + Стикер + Причина отчёта о контенте + ОТЧЁТ + Заблокировать пользователя + + Все сообщения (громко) + Без звука + Отправить данное сообщение под спойлером + Спойлер + Введите ключевые слова, чтобы найти отсебятину. + + Длительный щелчок по комнате открывает опции + + + Непрочитанные сообщения + + Развяжите своё общение + Общайтесь с людьми напрямую или в группах + Начать + + Выберите сервер + Как и электронная почта, учетные записи имеют один дом, хотя вы можете общаться с кем угодно + Премиум-хостинг для организаций + Узнать больше + Другое + Пользовательские и расширенные настройки + + Продолжить + Подключиться к %1$s + Подключиться к Modular + Подключиться к пользовательскому серверу + Зарегистрироваться + Войти в систему + Продолжить с SSO + + Модульный адрес + Адрес + Премиум-хостинг для организаций + Введите адрес Modular Riot или сервера, который вы хотите использовать. + Произошла ошибка при загрузке страницы: %1$s (%2$d) + Приложение не может войти на этот сервер, так как он поддерживает следующие типы входа: %1$s. +\nВы хотите войти с помощью веб-клиента\? + Извините, этот сервер не принимает новые учётные записи. + Приложение не может создать учётную запись на сём сервере. +\n +\nЖелаете зарегистрироваться через веб-клиент\? + + Сей адрес электронной почты не связан ни с одной учетной записью. + + Сбросить пароль на %1$s + Далее + Email + Новый пароль + + Внимание! + Смена пароля приведёт к сбросу всех сквозных ключей шифрования во всех ваших сеансах, что сделает зашифрованную историю разговоров нечитаемой. Настройте резервное копирование ключей или экспортируйте ключи от комнаты из другого сеанса, прежде чем сбрасывать пароль. + Продолжить + + Данный email не связан ни с одним аккаунтом + + Проверьте свою почту + Письмо с подтверждением было отправлено на %1$s. + Нажмите на ссылку, чтобы подтвердить свой новый пароль. Как только вы перейдете по ссылке, которую он содержит, нажмите ниже. + Успешно! + Ваш пароль был сброшен. + Вы вышли из всех сеансов и больше не будете получать push-уведомления. Чтобы снова иметь возможность получать уведомления, необходимо повторно войти в систему. + Назад, чтобы войти в систему + + Предупреждение + Ваш пароль еще не изменен. +\n +\nОстановить процесс смены пароля\? + + Установить адрес электронной почты + Электронная почта + Электронная почта (по желанию) + Далее + + Установить номер телефона + Укажите номер своего телефона, ежели желаете, чтобы люди, которым вы небезразличны, смогли вас найти. + Пожалуйста, используйте международный формат. + Номер телефона + Номер телефона (по желанию) + Далее + + Подтвердить номер телефона + Мы только что отправили код на %1$s. Введите его ниже, чтобы подтвердить, что это вы. + Введите код + Отправить повторно + Далее + + Международные телефонные номера должны начинаться с \'+\' + Номер телефона кажется недействительным. Пожалуйста, проверьте его + + Зарегистрироваться в %1$s + Имя пользователя или email + Имя пользователя + Пароль + Далее + Это имя пользователя занято + Предупреждение + Ваш аккаунт еще не создан. +\n +\nОстановить процесс регистрации\? + + Выбрать matrix.org + Выбрать modular + Выбрать учреждённый сервер + Пожалуйста, пройдите проверку на каптчу + Принять условия для продолжения + + Пожалуйста, проверьте ваш email + Мы только что отправили email на %1$s. +\nПожалуйста, нажмите на содержащуюся в нём ссылку, чтобы продолжить создание аккаунта. + Домашний сервер устарел + Сей домашний сервер использует слишком старую версию для подключения. Попросите вашего администратора обновить версию на домашнем сервере. + + + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунду… + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунды… + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунд… + + + Вы вышли из системы + Сие может быть обусловлено различными причинами: +\n +\n- Вы сменили пароль в другом сеансе. +\n +\n- Вы удалили сей сеанс из иного сеанса. +\n +\n- Администратор вашего сервера заблокировал вам доступ из соображений безопасности. + Войти снова + + Вы вышли из системы + Войти + Администратор вашего домашнего сервера (%1$s) вывел вас из вашего аккаунта %2$s (%3$s). + Войдите, чтобы восстановить ключи шифрования, хранящиеся исключительно на сём устройстве. Они нужны вам для чтения всех ваших защищённых сообщений на любом устройстве. + Войти + Пароль + Очистить личные данные + Внимание: Ваши личные данные (включая ключи шифрования) всё ещё хранятся на сём устройстве. +\n +\nОчистите его, если вы закончили использовать сие устройство или хотите войти в другую учётную запись. + Очистить все данные + + Очистить данные + Очистить все данные, хранящиеся в данный момент на сём устройстве\? +\nВойдите ещё раз, чтобы получить доступ к данным своего аккаунта и сообщениям. + Вы потеряете доступ к защищённым сообщениям, если не войдёте в систему для восстановления ключей шифрования. + Очистить данные + Текущая сессия предназначена для пользователя %1$s, а вы предоставляете учётные данные для пользователя %2$s. Такая безалаберность не поддерживается в RiotX. +\nПожалуйста, сначала очистите данные, а затем снова войдите под другим аккаунтом. + + Ваша ссылка на matrix.to неверна + Описание слишком короткое + + Посмотреть все мои сеансы + Дополнительные настройки + Режим разработчика + Режим разработчика активирует скрытые функции, а также может сделать приложение менее стабильным. Только для разработчиков! + Настройки + Текущий сеанс + Другие сеансы + + Включено шифрование + Недоверительный вход + Отправленные файлы + Интерактивная проверка по отсебятинам + Пожалуйста, выберите имя пользователя. + Пожалуйста, выберите пароль. From c9fb231714debfedf173deacdf1e5e680cb76d42 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 13 May 2020 11:32:29 +0000 Subject: [PATCH 102/199] Translated using Weblate (Swedish) Currently translated at 12.0% (200 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sv/ --- vector/src/main/res/values-sv/strings.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 6ba74af043..118290b1a0 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -219,4 +219,18 @@ Användarnamn Sätt en e-postadress för kontoåterförvärv, och senare för att valfritt vara upptäckbar av folk som som känner dig. Sätt ett telefonnummer som folk som känner dig kan använda för att hitta dig. + Sätt en e-postadress för kontoåterförvärv. Senare kan e-postadresser och telefonnummer valfritt användas för att vara upptäckbar av folk som känner dig. + Sätt en e-postadress för kontoåterförvärv. Senare kan e-postadresser och telefonnummer valfritt användas för att vara upptäckbar av folk som känner dig. + E-postadress + E-postadress (valfritt) + Telefonnummer + Telefonnummer (valfritt) + Repetera lösenordet + Bekräfta ditt nya lösenord + Fel användarnamn och/eller lösenord + Användarnamn får endast innehålla bokstäver, siffror, punkter, bindestreck och understreck + Lösenordet är för kort (minst 6 tecken) + Lösenord saknas + Det här ser inte ut som en giltig e-postadress + Det här ser inte ut som ett giltigt telefonnummer From 8cc82fe5ba7800488075f139123729359c0f04c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 14 May 2020 08:13:31 +0000 Subject: [PATCH 103/199] Added translation using Weblate (Estonian) --- matrix-sdk-android/src/main/res/values-et/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 matrix-sdk-android/src/main/res/values-et/strings.xml diff --git a/matrix-sdk-android/src/main/res/values-et/strings.xml b/matrix-sdk-android/src/main/res/values-et/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/matrix-sdk-android/src/main/res/values-et/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 5004fba986b140a51b6e0e44f1551b0121cf8a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 14 May 2020 08:16:34 +0000 Subject: [PATCH 104/199] Added translation using Weblate (Estonian) --- vector/src/main/res/values-et/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 vector/src/main/res/values-et/strings.xml diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/vector/src/main/res/values-et/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 06defaf14ef861263b0e3131de9ebe85e02599ab Mon Sep 17 00:00:00 2001 From: Tirifto Date: Thu, 14 May 2020 17:10:05 +0000 Subject: [PATCH 105/199] Translated using Weblate (Esperanto) Currently translated at 24.2% (404 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/eo/ --- vector/src/main/res/values-eo/strings.xml | 79 ++++++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index 2a2aceb733..dd6cc11f21 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -216,7 +216,7 @@ \n \nĈu vi volas iujn aldoni nun\? - Pluiĝi per… + pluiĝi per… Pardonu, troviĝis neniu ekstera aplikaĵo por ĉi tiu ago. Saluti @@ -241,7 +241,7 @@ Mankas pasvorto Ĉi tio ne ŝajnas esti valida retpoŝtadreso Ĉi tio ne ŝajnas esti valida telefonnumero - Ĉi tiu retpoŝtadreso jam estas difinita + Ĉi tiu retpoŝtadreso jam estas difinita. Mankas retpoŝtadreso Mankas telefonnumero Mankas retpoŝtadreso aŭ telefonnumero @@ -439,4 +439,77 @@ \nĈu vi certe volas daŭrigi\? Ni ne povis krei vian rektan babilon. Bonvolu kontroli la invitotajn uzantojn kaj reprovi. - +Por diagnozi problemojn, protokolo de ĉi tiu kliento sendiĝos kune kun ĉi tiu erar-raporto. Ĉi tiu erar-raporto, inkluzive la protokolon kaj la ekrankopion, ne estos publike videbla. Se vi preferus sendi nur la ĉi-supran tekston, bonvolu malmarki: + Ŝajnas, ke vi kolere skuas la telefonon. Ĉu vi volas malfermi la erar-raportilon\? + La aplikaĵo lastatempe fiaskis. Ĉu vi volas malfermi la fiasko-raportilon\? + Kolere skuu por raporti eraron + + Bonvolu enigi validan URL-on + La URL ne estas atingebla, bonvolu kontroli ĝin + Ĉi tio ne estas valida adreso de servilo de Matrix + Ne povas atingi hejmservilon je ĉi tiu URL, bonvolu kontroli ĝin + Via aparato uzas eksdatan sekurecan protokolon TLS, neŝirmatan kontraŭ atakoj; por via sekureco vi ne povos konektiĝi + Misformita JSON + Ne enhavis valdiajn JSON-datumojn + Tro multaj petoj sendiĝis + Ĉi tiu uzantonomo jam estas uzata + La retpoŝt-ligilo, kiu ankoraŭ ne estas klakita + + "Vi bezonas resaluti por generi tutvoje ĉifrajn ŝlosilojn por ĉi tiu salutaĵo kaj sendi la publikan ŝlosilon al via hejmservilo. +\nĈi tio necesas nur unufoje. +\nPardonu la maloportunon." + + Repeti ĉifrajn ŝlosilojn de aliaj viaj salutaĵoj. + + Peto de ŝlosilo sendiĝis. + + Peto sendiĝis. + Bonvolu ruli Rioton sur alia aparato kiu scipovas malĉifri la mesaĝon, por ke ĝi povu sendi al vi la ŝlosilojn al ĉi tiu salutaĵo. + + Envena voko + Envena vidvoko + Envena voĉvoko + Voko progresas… + Vidvoko progresas… + + Ne povas iniciati la filmilon + Foti aŭ filmi + Ne povas filmi + + Informoj + Riot bezonas permeson aliri viajn fotojn kaj filmojn, por sendi kaj konservi kunsendaĵojn. +\n +\nBonvolu permesi aliron per la sekva ŝprucpeto, por povi sendi dosierojn el via telefono. + Riot bezonas permeson aliri vian filmilon por foti kaj vidvoki. + " +\n +\nBonvolu permesi aliron per la sekva ŝprucpeto, por ebligi la vokon." + Riot bezonas permeson aliri vian mikrofonon por fari voĉvokojn. + " +\n +\nBonvolu permesi aliron per la sekva ŝprucpeto, por ebligi la vokon." + Riot bezonsa premeson aliri viajn filmilon kaj mikrofonon por fari vidvokojn. +\n +\nBonvolu permesi aliron per la sekva ŝprucpeto, por ebligi la vokon. + Riot povas kontroli vian adresaron por trovi aliajn uzantojn de Matrix per iliaj retpoŝtadresoj kaj telefonnumeroj. Se vi konsentas kunhavi vian adresaron por tiu celo, bonvolu permesi aliron per la sekva ŝprucpeto. + Riot povas kontroli vian adresaron por trovi aliajn uzantojn de Matrix per iliaj retpoŝtadresoj kaj telefonnumeroj. +\n +\nĈu vi konsentas kunhavi vian adresaron por tiu celo\? + + Pardonu. Ago ne efektiviĝis, pro mankantaj permesoj + + Konservite + Ĉu konservi al elŝutujo\? + JES + NE + Daŭrigi + + Forigi + Aliĝi + Antaŭrigardi + Rifuzi + + Listigi ĉambranojn + Spegulante… + Vi estis invitita al ĉi tiu ĉambro de %s + From b2bacdfa4ec53ec01a474f3721e56bf7667a0f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 14 May 2020 08:14:10 +0000 Subject: [PATCH 106/199] Translated using Weblate (Estonian) Currently translated at 92.6% (151 of 163 strings) Translation: Riot Android/RiotX Matrix SDK Translate-URL: https://translate.riot.im/projects/riot-android/riotx-matrix-sdk/et/ --- .../src/main/res/values-et/strings.xml | 189 +++++++++++++++++- 1 file changed, 187 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-et/strings.xml b/matrix-sdk-android/src/main/res/values-et/strings.xml index a6b3daec93..e51360b6c9 100644 --- a/matrix-sdk-android/src/main/res/values-et/strings.xml +++ b/matrix-sdk-android/src/main/res/values-et/strings.xml @@ -1,2 +1,187 @@ - - \ No newline at end of file + +%1$s: %2$s + %1$s saatis pildi. + %1$s saatis kleepsu. + + Kasutaja %s kutse + %1$s kutsus kasutajat %2$s + %1$s kutsus sind + %1$s liitus jututoaga + %1$s lahkus jututoast + %1$s lükkas tagasi kutse + %1$s müksas kasutajat %2$s + %1$s võttis tagasi kutse kasutajale %2$s + %1$s muutis oma avatari + %1$s määras oma kuvatavaks nimeks %2$s + %1$s muutis senise kuvatava nime %2$s uueks nimeks %3$s + %1$s eemaldas oma kuvatava nime (%2$s) + %1$s muutis uueks teemaks %2$s + %1$s muutis jututoa uueks nimeks %2$s + %s alustas videokõnet. + %s alustas häälkõnet. + %s vastas kõnele. + %s lõpetas kõne. + %1$s seadistas, et tulevane jututoa ajalugu on nähtav kasutajale %2$s + kõikidele jututoa liikmetele alates kutsumise hetkest. + kõikidele jututoa liikmetele alates liitumise hetkest. + kõikidele jututoa liikmetele. + kõikidele. + teadmata (%s). + %1$s lülitas sisse läbiva krüptimise (%2$s) + %s uuendas seda jututuba. + + %1$s saatis VoIP konverentsi kutse + VoIP-konverents algas + VoIP-konverents lõppes + + (samuti sai avatar muudetud) + %1$s eemaldas jututoa nime + %1$s eemaldas jututoa teema + Sõnum on eemaldatud + Sõnum on eemaldatud %1$s poolt + Sõnum on eemaldatud [põhjus: %1$s] + Sõnum on eemaldatud %1$s poolt [põhjus: %2$s] + %1$s uuendas oma profiili %2$s + %1$s saatis jututoaga liitumiseks kutse kasutajale %2$s + %1$s võttis tagasi jututoaga liitumise kutse kasutajalt %2$s + %1$s võttis vastu kutse %2$s nimel + + ** Ei õnnestu dekrüptida: %s ** + Sõnumi saatja seade ei ole selle sõnumi jaoks saatnud dekrüptimisvõtmeid. + + Vastuseks kasutajale + + Ei saanud muuta sõnumit + Sõnumi saatmine ei õnnestunud + + Faili üles laadimine ei õnnestunud + + Võrguühenduse viga + Matrix\'i viga + + Hetkel ei ole võimalik uuesti liituda tühja jututoaga. + + Krüptitud sõnum + + E-posti aadress + Telefoninumber + + saatis pildi. + saatis video. + saatis helifaili. + saatis faili. + + Kutse kasutajalt %s + Kutse jututuppa + + %1$s ja %2$s + + + %1$s ja üks muu + %1$s ja %2$d muud + + + Tühi jututuba + + + Koer + Kass + Lõvi + Hobune + Ükssarvik + Siga + Elevant + Jänes + Panda + Kukk + Pingviin + Kilpkonn + Kala + Kaheksajalg + Liblikas + Lill + Puu + Kaktus + Seen + Maakera + Kuu + Pilv + Tuli + Banaan + Õun + Maasikas + Mais + Pitsa + Kook + Süda + Smaili + Robot + Müts + Prillid + Mutrivõti + Jõuluvana + Pöidlad püsti + Vihmavari + Liivakell + Kell + Kingitus + Lambipirn + Raamat + Pliiats + Kirjaklamber + Käärid + Lukk + Võti + Haamer + Telefon + Lipp + Rong + Jalgratas + Lennuk + Rakett + Auhind + Pall + Kitarr + Trompet + Kelluke + Ankur + Kõrvaklapid + Kaust + Knopka + + Alglaadimine: +\nImpordin kontot… + Alglaadimine: +\nImpordin krüptoseadistusi + Alglaadimine: +\nImpordin jututubasid + Alglaadimine: +\nImpordin liitutud jututubasid + Alglaadimine: +\nImpordin kutsutud jututubasid + Alglaadimine: +\nImpordin lahkutud jututubasid + Alglaadimine: +\nImpordin kogukondi + Alglaadimine: +\nImpordin kontoandmeid + + Saadan sõnumit… + Tühjenda saatmisjärjekord + + Kasutaja %1$s kutse. Põhjus: %2$s + %1$s kutsus kasutajat %2$s. Põhjus: %3$s + %1$s kutsus sind. Põhjus: %2$s + %1$s liitus jututoaga. Põhjus: %2$s + %1$s lahkus jututoast. Põhjus: %2$s + %1$s lükkas kutse tagasi. Põhjus: %2$s + %1$s müksas välja kasutaja %2$s. Põhjus: %3$s + %1$s saatis kasutajale %2$s kutse jututoaga liitumiseks. Põhjus: %3$s + %1$s tühistas kasutajale %2$s saadetud kutse jututoaga liitumiseks. Põhjus: %3$s + %1$s võttis vastu kutse %2$s jututoaga liitumiseks. Põhjus: %3$s + %1$s võttis tagasi kasutajale %2$s saadetud kutse. Põhjus: %3$s + + %1$s lülitas sisse läbiva krüptimise. + %1$s lülitas sisse läbiva krüptimise (tundmatu algoritm %2$s). + + From c03d61e09f8cfdb0ad7178305990079b2d56c800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Thu, 14 May 2020 08:17:24 +0000 Subject: [PATCH 107/199] Translated using Weblate (Estonian) Currently translated at 1.5% (25 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/et/ --- vector/src/main/res/values-et/strings.xml | 34 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index a6b3daec93..88f6d84c7d 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -1,2 +1,32 @@ - - \ No newline at end of file + +et + EE + Latn + + Hele teema + Tume teema + Must teema + Status.im teema + + Käivitan teenuse + Sünkroniseerin… + Kuulan, kas leidub sündmusi + Lärmakad teavitused + Vaiksed teavitused + + Sõnumid + Jututuba + Seadistused + Jututoa liikme üksikasjad + Ajalooline + Veateade + Kogukonna üksikasjad + Saada kleeps + Võtmete varundus + Kasuta võtmete varundust + Verifitseeri sessioon + + Võtmete varundus pole veel valmis, oota natuke… + Krüptitud sõnum + + From 885dac4ad16a5a25a597bbb0d96bcbf20289561c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 09:59:57 +0000 Subject: [PATCH 108/199] Translated using Weblate (French) Currently translated at 100.0% (1672 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/fr/ --- vector/src/main/res/values-fr/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index a8e72864f4..13f3808328 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -1560,7 +1560,7 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq Merci, la suggestion a bien été envoyée Échec d’envoi de la suggestion (%s) - Afficher les évènements cachés dans l’historique + Afficher les évènements cachés dans les discussions RiotX − Client Matrix nouvelle génération Un client pour Matrix plus rapide et plus léger utilisant les derniers frameworks Android @@ -1600,7 +1600,7 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq Nom ou identifiant (#exemple:matrix.org) - Activer le balayement pour répondre dans l’historique + Activer le balayement pour répondre dans les discussions Lien copié dans le presse-papiers @@ -2102,7 +2102,7 @@ Si vous n’avez pas configuré de nouvelle méthode de récupération, un attaq Envoie le message fourni coloré comme un arc-en-ciel Envoie la réaction fournie colorée comme un arc-en-ciel - Historique + Discussions Éditeur de messages From 308828ef502379bf66fe6235cb39ce95b82b94a2 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Thu, 14 May 2020 18:11:02 +0000 Subject: [PATCH 109/199] Translated using Weblate (Swedish) Currently translated at 14.3% (239 of 1672 strings) Translation: Riot Android/RiotX application Translate-URL: https://translate.riot.im/projects/riot-android/riotx-application/sv/ --- vector/src/main/res/values-sv/strings.xml | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 118290b1a0..abbd157553 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -233,4 +233,49 @@ Lösenord saknas Det här ser inte ut som en giltig e-postadress Det här ser inte ut som ett giltigt telefonnummer + Den här e-postadressen är redan definierad. + E-postadress saknas + Telefonnummer saknas + E-postadress eller telefonnummer saknas + Felaktig token + Lösenorden matchar inte + Glömt lösenordet\? + Använd anpassade server-inställningar (avancerat) + Vänligen kolla din e-post för att fortsätta med registreringen + Registrering med e-postadress och telefonnummer samtidigt så stöds inte än, fram tills API:t finns. Endast telefonnumret kommer användas. +\n +\nDu kan lägga till ett telefonnummer till din profil i inställningarna. + Denna hemserver skulle vilja verifiera att du inte är en robot + Användarnamnet är upptagen + Hemserver: + Identitetsserver: + Jag har verifierat min e-postadress + För att återställa ditt lösenord, skriv in e-postadressen länkad till ditt konto: + Du måste skriva in e-postadressen länkad till ditt konto. + Du måste skriva in ett nytt lösenord. + Ett e-brev har skickats till %s. När du har följt länken i det, klicka nedan. + Misslyckades att verifiera e-postadressen: se till att du klickade på länken i e-brevet + Ditt lösenord har blivit återställt. +\n +\nDu har loggats ut ur alla sessioner och kommer inte längre motta pushnotifikationer. För att återaktivera notifikationer, logga in igen på varje enhet. + Vänligen granska och acceptera villkoren för denna hemserver: + + URLen måste börja med http[s]:// + Kan inte logga in: Nätverksfel + Kan inte logga in + Kan inte registrera: Nätverksfel + Kan inte registrera + Kan inte registrera: fel vid med e-postägandeskap + Vänligen skriv in en giltig URL + Den här URLen kan inte nås, vänligen kolla den + Det här är inte en giltig Matrixserveradress + Kan inte nå en hemserver på den här URLen, vänligen kolla den + Din enhet använder ett utdaterat TLS-protokoll, sårbart för anfall, så för din säkerhets skull så kommer du inte kunna ansluta + Mobil + + Felaktigt användarnamn/lösenord + Den åtkomsttoken du specificerade kändes inte igen + Felformaterad JSON + Innehöll inte giltig JSON + För många förfrågningar har skickats From 7a2aefd8fb19265393d6f09b6d1872f7e85a9264 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 12:45:23 +0200 Subject: [PATCH 110/199] Format string resources --- .../src/main/res/values-eo/strings.xml | 20 +++--- .../src/main/res/values-et/strings.xml | 11 ++-- .../src/main/res/values-fi/strings.xml | 2 +- vector/src/main/res/values-de/strings.xml | 8 +-- vector/src/main/res/values-eo/strings.xml | 24 +++---- vector/src/main/res/values-et/strings.xml | 5 +- vector/src/main/res/values-fi/strings.xml | 28 ++++----- vector/src/main/res/values-hu/strings.xml | 4 +- vector/src/main/res/values-nb-rNO/strings.xml | 4 +- vector/src/main/res/values-nl/strings.xml | 4 +- vector/src/main/res/values-pl/strings.xml | 62 +++++++++---------- vector/src/main/res/values-ru/strings.xml | 44 ++++++------- vector/src/main/res/values-sq/strings.xml | 2 +- vector/src/main/res/values-sv/strings.xml | 11 ++-- 14 files changed, 116 insertions(+), 113 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-eo/strings.xml b/matrix-sdk-android/src/main/res/values-eo/strings.xml index db73db86e2..69600394ac 100644 --- a/matrix-sdk-android/src/main/res/values-eo/strings.xml +++ b/matrix-sdk-android/src/main/res/values-eo/strings.xml @@ -19,7 +19,7 @@ Responde al -%1$s: %2$s + %1$s: %2$s %1$s ŝanĝis sian vidigan nomon al %2$s %1$s ŝanĝis sian vidigan nomon de %2$s al %3$s %1$s forigis sian vidigan nomon (%2$s) @@ -73,9 +73,9 @@ %1$s kaj %2$s - %1$s kaj 1 alia - %1$s kaj %2$d aliaj - + %1$s kaj 1 alia + %1$s kaj %2$d aliaj + Malplena ĉambro @@ -187,14 +187,14 @@ %1$s nuligis la inviton al %2$s. Kialo: %3$s - %1$s aldonis %2$s kiel adreson por ĉi tiu ĉambro. - %1$s aldonis %2$s kiel adresojn por ĉi tiu ĉambro. - + %1$s aldonis %2$s kiel adreson por ĉi tiu ĉambro. + %1$s aldonis %2$s kiel adresojn por ĉi tiu ĉambro. + - %1$s forigis %2$s kiel adreson por ĉi tiu ĉambro. - %1$s forigis %2$s kiel adresojn por ĉi tiu ĉambro. - + %1$s forigis %2$s kiel adreson por ĉi tiu ĉambro. + %1$s forigis %2$s kiel adresojn por ĉi tiu ĉambro. + %1$s aldonis %2$s kaj forigis %3$s kiel adresojn por ĉi tiu ĉambro. diff --git a/matrix-sdk-android/src/main/res/values-et/strings.xml b/matrix-sdk-android/src/main/res/values-et/strings.xml index e51360b6c9..1d52c2a7a1 100644 --- a/matrix-sdk-android/src/main/res/values-et/strings.xml +++ b/matrix-sdk-android/src/main/res/values-et/strings.xml @@ -1,5 +1,6 @@ -%1$s: %2$s + + %1$s: %2$s %1$s saatis pildi. %1$s saatis kleepsu. @@ -77,9 +78,9 @@ %1$s ja %2$s - %1$s ja üks muu - %1$s ja %2$d muud - + %1$s ja üks muu + %1$s ja %2$d muud + Tühi jututuba @@ -184,4 +185,4 @@ %1$s lülitas sisse läbiva krüptimise. %1$s lülitas sisse läbiva krüptimise (tundmatu algoritm %2$s). - + diff --git a/matrix-sdk-android/src/main/res/values-fi/strings.xml b/matrix-sdk-android/src/main/res/values-fi/strings.xml index ecb2edd303..8dd87b6b6a 100644 --- a/matrix-sdk-android/src/main/res/values-fi/strings.xml +++ b/matrix-sdk-android/src/main/res/values-fi/strings.xml @@ -209,6 +209,6 @@ %1$s laittoi päälle osapuolten välisen salauksen. %1$s laittoi päälle osapuolisten välisen salauksen (tuntematon algoritmi %2$s). -%s haluaa varmentaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten varmennusta. Joudut käyttämään perinteistä varmennustapaa. + %s haluaa varmentaa salausavaimesi, mutta asiakasohjelmasi ei tue keskustelun aikana tapahtuvaa avainten varmennusta. Joudut käyttämään perinteistä varmennustapaa. diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 8cb293fc1b..c0c967fd63 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1300,9 +1300,9 @@ Dieser Fehler ist außerhalb von Riot passiert. Es gibt kein Google-Konto auf de Sicherung wiederhergestellt %s ! %1$d Sitzungsschlüssel wurde(n) wiederhergestellt und %2$d vorher unbekannte(r) Schlüssel wurde(n) hinzugefügt - Backup mit %d Schlüssel wiederhergestellt. - Backup mit %d Schlüsseln wiederhergestellt. - + Backup mit %d Schlüssel wiederhergestellt. + Backup mit %d Schlüsseln wiederhergestellt. + %d neuer Schlüssel wurde dieser Sitzung hinzugefügt. %d neue Schlüssel wurden dieser Sitzung hinzugefügt. @@ -2352,7 +2352,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Kopier es in deinen persönlichen Cloud-Speicher Verschlüsselung ist nicht aktiviert -Dies kann nicht von einem mobilen Gerät erfolgen + Dies kann nicht von einem mobilen Gerät erfolgen Wenn Räume verbessert werden Verschlüsselung aktiviert diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index dd6cc11f21..f3e7c65d67 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -99,7 +99,7 @@ Kontroli salutaĵon Kontroli aparaton -Latn + Latn Haŭto de Status.im @@ -160,9 +160,9 @@ Neniuj ĉambroj Neniuj publikaj ĉambroj disponeblas - 1 uzanto - %d uzantoj - + 1 uzanto + %d uzantoj + Inviti Komunumoj @@ -298,9 +298,9 @@ Vokoj Pravalorigante servon - 1 elektita - %d elektitaj - + 1 elektita + %d elektitaj + Misformita identigilo. Ĝi devus esti retpoŝtadreso aŭ identigilo de Matrix, kiel «@lokaparto:mallokaparto» INVITITA ALIĜINTA @@ -325,9 +325,9 @@ Aliĝi al ĉambro Aliĝi al ĉambro - 1 ĉambro - %d ĉambroj - + 1 ĉambro + %d ĉambroj + Ĉiuj mesaĝoj Nur mencioj Silentigi @@ -439,7 +439,7 @@ \nĈu vi certe volas daŭrigi\? Ni ne povis krei vian rektan babilon. Bonvolu kontroli la invitotajn uzantojn kaj reprovi. -Por diagnozi problemojn, protokolo de ĉi tiu kliento sendiĝos kune kun ĉi tiu erar-raporto. Ĉi tiu erar-raporto, inkluzive la protokolon kaj la ekrankopion, ne estos publike videbla. Se vi preferus sendi nur la ĉi-supran tekston, bonvolu malmarki: + Por diagnozi problemojn, protokolo de ĉi tiu kliento sendiĝos kune kun ĉi tiu erar-raporto. Ĉi tiu erar-raporto, inkluzive la protokolon kaj la ekrankopion, ne estos publike videbla. Se vi preferus sendi nur la ĉi-supran tekston, bonvolu malmarki: Ŝajnas, ke vi kolere skuas la telefonon. Ĉu vi volas malfermi la erar-raportilon\? La aplikaĵo lastatempe fiaskis. Ĉu vi volas malfermi la fiasko-raportilon\? Kolere skuu por raporti eraron @@ -512,4 +512,4 @@ Listigi ĉambranojn Spegulante… Vi estis invitita al ĉi tiu ĉambro de %s - + diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 88f6d84c7d..3ec6bf684a 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -1,5 +1,6 @@ -et + + et EE Latn @@ -29,4 +30,4 @@ Võtmete varundus pole veel valmis, oota natuke… Krüptitud sõnum - + diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index fcd2dcad43..72addef9e4 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -2075,7 +2075,7 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Ei turvallinen Video. Kuva. -Pyyntö annetun käyttäjä-ID:n vahvistamiseksi + Pyyntö annetun käyttäjä-ID:n vahvistamiseksi Johonkin näistä on mahdollisesti murtauduttu: \n \n - Kotipalvelimesi @@ -2162,9 +2162,9 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Vahvista tämä istunto jotta se merkitään luotetuksi ja se saa pääsyn salattuihin viesteihin. Jos et ole kirjautunut tähän istuntoon, tunnuksesi on saattanut vuotaa hyökkääjälle: - %d käynnissä oleva istunto - %d käynnissä olevaa istuntoa - + %d käynnissä oleva istunto + %d käynnissä olevaa istuntoa + Varmenna tämä kirjautuminen Muut käyttäjät eivät välttämättä luota siihen @@ -2197,13 +2197,13 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Kehittäjän työkalut - %d ääni - %d ääntä - + %d ääni + %d ääntä + - %d ääni - lopulliset tulokset - %d ääntä - lopulliset tulokset - + %d ääni - lopulliset tulokset + %d ääntä - lopulliset tulokset + Luo yksinkertaisen äänestyksen Jos et pääse käsiksi olemassaolevaan istuntoon @@ -2213,9 +2213,9 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Poista… Haluatko lähettää tämän liitteen %1$s\?:lle\? - Lähetä kuva alkuperäisessä koossa - Lähetä kuvat alkuperäisessä koossa - + Lähetä kuva alkuperäisessä koossa + Lähetä kuvat alkuperäisessä koossa + Vahvista poisto Haluatko varmasti poistaa tämän tapahtuman\? Huomaa, että jos poistat huoneen nimen tai otsikon muutostapahtuman, se voi perua muutoksen. @@ -2288,4 +2288,4 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös Syy poistoon Viestin avain - + diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 8587b82515..acdb4bf5b2 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2382,10 +2382,10 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró Kérlek válassz jelszót. Ezt a hivatkozást ellenőrizd le még egyszer A közvetlen üzenetedet nem sikerült elkészíteni. Ellenőrizd azokat a felhasználókat akiket meg szeretnél hívni és próbáld újra. -Használd a legújabb Riotot a másik eszközödön, úgy mint Riot Web, Asztali Riot, RiotX for Android vagy más eszközök közötti hitelesítést támogató másik Matrix klienst + Használd a legújabb Riotot a másik eszközödön, úgy mint Riot Web, Asztali Riot, RiotX for Android vagy más eszközök közötti hitelesítést támogató másik Matrix klienst Erősítsd meg ebben a bejelentkezésben a személyazonosságodat egy másik munkamenetből, hogy hozzáférhess a titkosított üzenetekhez. %1$s hivatkozás egy másik oldalra visz: %2$s. \n \nFolytatod\? - + diff --git a/vector/src/main/res/values-nb-rNO/strings.xml b/vector/src/main/res/values-nb-rNO/strings.xml index 86cb713dbb..26aa4c3ff8 100644 --- a/vector/src/main/res/values-nb-rNO/strings.xml +++ b/vector/src/main/res/values-nb-rNO/strings.xml @@ -723,7 +723,7 @@ Send inn i Hjemmetjener URL Start ny chat -Start lydsamtale + Start lydsamtale Start videosamtale Send lydopptak @@ -731,4 +731,4 @@ Er du sikker på du vil starte en samtale med %s\? Er du sikker på du vil starte en lydsamtale\? Er du sikker på du vil starte en videosamtale\? - + diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 8880cd2b5e..7d7e8e72e0 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -1605,7 +1605,7 @@ U gebruikt geen identiteitsserver Er is geen identiteitsserver geconfigureerd. Dit is vereist om uw wachtwoord opnieuw in te stellen. -Vorige versies van Riot hadden een veiligheidsfout die er voor kon zorgen dat je Identiteits Server (%1$s) toegang tot je account had. Indien je %2$s vertrouwt, dan kun je dit negeren; anders log je uit en weer in. + Vorige versies van Riot hadden een veiligheidsfout die er voor kon zorgen dat je Identiteits Server (%1$s) toegang tot je account had. Indien je %2$s vertrouwt, dan kun je dit negeren; anders log je uit en weer in. \n \nLees meer details hier: \nhttps://medium.com/@RiotChat/36b4792ea0d6 @@ -1660,4 +1660,4 @@ Gespreksnaam Publiek Iedereen zal dit gesprek kunnen toetreden - + diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index ca0ae9e542..301ae3299e 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -588,7 +588,7 @@ Możesz dodać adres e-mail do swojego profilu w ustawieniach. %d zmiana członkostwa %d zmiany członkostwa %d zmian członkostwa - + Rozmówca nie połączył się. @@ -615,13 +615,13 @@ Przyznaj dostęp w następnym oknie. Jeden aktywny członek Kilku aktywnych członków %d aktywnych członków - + 1 członek kilku członków %d członków - + Nie będziesz w stanie cofnąć tej zmiany, ponieważ przyznajesz użytkownikowi uprawnienia równe swoim. @@ -638,7 +638,7 @@ Jesteś pewien? Nowa wiadomość Kilka nowych wiadomości %d nowych wiadomości - + Może to oznaczać że ktoś zakłóca twoje połączenie, lub Twój telefon nie ufa certyfikatowi dostarczonemu przez zdalny serwer. @@ -652,13 +652,13 @@ Jesteś pewien? 1 pokój %d pokoje %d pokoi - + %1$s pokój znaleziony dla %2$s Kilka pokoi znalezionych dla %2$s %1$s pokoi znalezionych dla %2$s - + Wszystkie wiadomości (hałaśliwy) Wszystkie wiadomości @@ -804,13 +804,13 @@ Możesz to zrobić teraz lub później z poziomu ustawień aplikacji. 1 pokój %d pokoje %d pokoi - + 1 aktywny widżet %d aktywne widżety %d aktywnych widżetów - + Pokój %s nie jest widoczny. @@ -832,13 +832,13 @@ Czy chcesz dodać teraz kilka? 1 nieprzeczytana wiadomość powiadomienia %d nieprzeczytane wiadomości powiadomienia %d nieprzeczytanych wiadomości powiadomienia - + 1 nieprzeczytana wiadomość powiadomienia %d nieprzeczytane wiadomości powiadomienia %d nieprzeczytanych wiadomości powiadomienia - + %1$s w %2$s @@ -923,14 +923,14 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo 1 członek %d członków - + 1 pokój %d pokoje %d pokoi - + Kliknij tutaj, aby zobaczyć starsze wiadomości @@ -945,22 +945,22 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo 1 sekunda %d sek. - + 1 minuta %d min. - + 1 godzina %s godz. - + 1 dzień %d dni - + Pokazać wszystkie wiadomości od tego użytkownika? @@ -969,7 +969,7 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas. 1 zaznaczone %d zaznaczone %d zaznaczonych - + Wersja %s Podgląd mediów przed wysłaniem @@ -1040,7 +1040,7 @@ Pamiętaj ta akcja może zresetować aplikacje i potrwać jakiś czas. Czy chcesz wyrzucić tego użytkownika z rozmowy\? Czy chcesz wyrzucić tych użytkowników z rozmowy\? - + Formatowanie Markdown Pokaż zdarzenia dołączenia i wyjścia @@ -1167,7 +1167,7 @@ Spróbuj uruchomić ponownie aplikację. Przywrócono kopię zapasową z %d kluczem. Przywrócono kopię zapasową z %d kluczami. - + Użyj kopii zapasowej klucza Uruchamianie… (%1$d z %2$d) @@ -1486,12 +1486,12 @@ Spróbuj uruchomić ponownie aplikację. %1$s: 1 wiadomość %1$s: %2$d wiadomości - + %d powiadomienie %d powiadomień - + Nowe wydarzenie @@ -1621,7 +1621,7 @@ Spróbuj uruchomić ponownie aplikację. Kopiowanie %d klucza… Kopiowanie %d kluczy… - + Nieprawidłowa odpowiedź funkcji autoodkrywania serwera domowego @@ -1779,7 +1779,7 @@ Spróbuj uruchomić ponownie aplikację. 1 użytkownik odczytał %d użytkowników odczytało - + Wystąpił błąd poczas otrzymywania załącznika. @@ -1924,7 +1924,7 @@ Spróbuj uruchomić ponownie aplikację. Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundę… Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundy… - + Wylogowałeś(-łaś) się @@ -2042,7 +2042,7 @@ Spróbuj uruchomić ponownie aplikację. Jedna osoba %1$d osób - + Opuszczanie pokoju… @@ -2117,7 +2117,7 @@ Spróbuj uruchomić ponownie aplikację. %d aktywna sesja %d aktywnych sesji - + Zweryfikuj tą sesję @@ -2154,12 +2154,12 @@ Spróbuj uruchomić ponownie aplikację. %d głos %d głosów - + %d głos - wyniki końcowe %d głosów - wyniki końcowe - + Wybrana Opcja Tworzy prostą ankietę @@ -2178,7 +2178,7 @@ Spróbuj uruchomić ponownie aplikację. Wyślij obraz w oryginalnym rozmiarze Wyślij obrazy w oryginalnym rozmiarze - + Potwierdź Usunięcie @@ -2239,7 +2239,7 @@ Spróbuj uruchomić ponownie aplikację. Tryb programisty aktywuje ukryte funkcje i może również spowodować, że aplikacja będzie mniej stabilna. Tylko dla programistów! Wiadomości w tym pokoju nie są szyfrowane end-to-end. Przesłane pliki -Prośby o klucze + Prośby o klucze Odblokuj historię zaszyfrowanych wiadomości @@ -2249,4 +2249,4 @@ Spróbuj uruchomić ponownie aplikację. Użyj tej sesji do weryfikacji nowej, nadając jej dostęp do zaszyfrowanych wiadomości. To nie ja - + diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 654b12c712..5837fa39ad 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -96,7 +96,7 @@ %d пользователь %d пользователя %d пользователей - + Отправить логи @@ -838,13 +838,13 @@ %d комната %d комнаты %d комнат - + %d комната %d комнаты %d комнат - + %1$s в %2$s @@ -852,7 +852,7 @@ %d активный виджет %d активных виджета %d активных виджетов - + @@ -862,45 +862,45 @@ %d активный участник %d активных участника %d активных участников - + %d участник %d участника %d участников - + %d новое сообщение %d новых сообщения %d новых сообщений - + %1$s комната найдена для %2$s %1$s комнаты найдено для %2$s %1$s комнат найдено для %2$s - + %d изменение членства %d изменения членства %d изменений членства - + %d непрочитанное уведомление %d непрочитанных уведомления %d непрочитанных уведомлений - + %d непрочитанное уведомление %d непрочитанных уведомления %d непрочитанных уведомлений - + Получить аватар Заметка аватара @@ -1038,20 +1038,20 @@ %d выбран %d выбрано %d выбраны - + %d участник %d участника %d участников - + %d комната %d комнаты %d комнат - + Системные оповещения @@ -1339,7 +1339,7 @@ %d новый ключ был добавлен к этому устройству. %d новых ключа были добавлены к этому устройству. %d новых ключей были добавлены к этому устройству. - + @@ -1391,7 +1391,7 @@ Резервное копирование %d ключа… Резервное копирование %d ключей… Резервное копирование %d ключей… - + Все ключи сохранены @@ -1847,7 +1847,7 @@ Подробные логи помогут разработчикам, предоставив больше информации, когда вы отправляете RageShake. Даже когда они разрешены, приложение не логирует ваши сообщения и другие приватные данные. -Закройте меню создания комнаты… + Закройте меню создания комнаты… Вниз Контакт @@ -1969,10 +1969,10 @@ Сей домашний сервер использует слишком старую версию для подключения. Попросите вашего администратора обновить версию на домашнем сервере. - Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунду… - Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунды… - Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунд… - + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунду… + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунды… + Слишком много запросов было отправлено. Вы сможете повторить попытку через %1$d секунд… + Вы вышли из системы Сие может быть обусловлено различными причинами: @@ -2021,4 +2021,4 @@ Интерактивная проверка по отсебятинам Пожалуйста, выберите имя пользователя. Пожалуйста, выберите пароль. - + diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 7f771a81ea..1696a02aef 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2278,7 +2278,7 @@ Që të garantoni se s’ju shpëton gjë, thjesht mbajeni të aktivizuar mekani Emër përdoruesi dhe/ose fjalëkalim i pasaktë. Fjalëkalimi i dhënë fillon ose mbaron me hapësirë, ju lutemi, kontrollojeni. - + Po publikohen kyçe të krijuar identiteti Mesazh… diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index abbd157553..40e2df9870 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -1,5 +1,6 @@ -sv + + sv SE Latn @@ -141,9 +142,9 @@ Inga rum Inga publika rum tillgängliga - 1 användare - %d användare - + 1 användare + %d användare + Bjud in Gemenskaper @@ -278,4 +279,4 @@ Felformaterad JSON Innehöll inte giltig JSON För många förfrågningar har skickats - + From ea1c75c16aabe0df3bec96b943aafb7c3b5d2f35 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 12:58:14 +0200 Subject: [PATCH 111/199] Fix lint issues in Strings --- vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-eo/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index c0c967fd63..1071b975d3 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1706,7 +1706,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Konnte keine Verbindung zum Heimserver herstellen Latn - Bitte fragen Sie den Administrator Ihres Home-Servers nach der Einrichtung eines TURN-Servers, damit Anrufe zuverlässig funktionieren. + Bitte fragen Sie den Administrator Ihres Home-Servers (%1$s) nach der Einrichtung eines TURN-Servers, damit Anrufe zuverlässig funktionieren. \n \nAlternativ können Sie einen öffentlichen Server auf %2$s nutzen. Dies wird jedoch weniger zuverlässig sein und Ihre IP-Adresse gegenüber diesem Server preisgeben. Sie können dies auch in den Einstellungen anpassen. Dies ist keine Adresse eines Matrixservers diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index f3e7c65d67..55bcd09d3a 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -197,8 +197,8 @@ Sendi voĉon Ĉu vi certe volas komenci novan babilon kun %s\? - Ĉu vi certe volas komenci novan voĉvokon kun %s\? - Ĉu vi certe volas komenci novan vidvokon kun %s\? + Ĉu vi certe volas komenci novan voĉvokon\? + Ĉu vi certe volas komenci novan vidvokon\? Voko malsukcesis pro misagordita servilo Bonvolu peti de la administranto de via hejmservilo (%1$s) agordon de TURN-servilo, por dependebla funkciigo de vokoj. \n From 8eebcef4e91de9ad10f48557bc39068b3f5b04cb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 15:36:52 +0200 Subject: [PATCH 112/199] Fix #1373 --- .../vector/matrix/android/api/session/user/model/User.kt | 3 +++ .../riotx/features/invite/InviteUsersToRoomViewModel.kt | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt index 753c9b609c..9f4f997b3b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/user/model/User.kt @@ -22,6 +22,9 @@ package im.vector.matrix.android.api.session.user.model */ data class User( val userId: String, + /** + * For usage in UI, consider using [getBestName] + */ val displayName: String? = null, val avatarUrl: String? = null ) { diff --git a/vector/src/main/java/im/vector/riotx/features/invite/InviteUsersToRoomViewModel.kt b/vector/src/main/java/im/vector/riotx/features/invite/InviteUsersToRoomViewModel.kt index 07c0cdbc7d..fc2f34b7a0 100644 --- a/vector/src/main/java/im/vector/riotx/features/invite/InviteUsersToRoomViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/invite/InviteUsersToRoomViewModel.kt @@ -66,13 +66,13 @@ class InviteUsersToRoomViewModel @AssistedInject constructor(@Assisted { val successMessage = when (selectedUsers.size) { 1 -> stringProvider.getString(R.string.invitation_sent_to_one_user, - selectedUsers.first().displayName) + selectedUsers.first().getBestName()) 2 -> stringProvider.getString(R.string.invitations_sent_to_two_users, - selectedUsers.first().displayName, - selectedUsers.last().displayName) + selectedUsers.first().getBestName(), + selectedUsers.last().getBestName()) else -> stringProvider.getQuantityString(R.plurals.invitations_sent_to_one_and_more_users, selectedUsers.size - 1, - selectedUsers.first().displayName, + selectedUsers.first().getBestName(), selectedUsers.size - 1) } _viewEvents.post(InviteUsersToRoomViewEvents.Success(successMessage)) From 03fa0e6ad6d786818e88e8f3e27826cd9ed924d2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 15:44:36 +0200 Subject: [PATCH 113/199] Prepare release 0.20.0 --- CHANGES.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 836ecdfaf9..869b034f45 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,4 @@ -Changes in RiotX 0.20.0 (2020-XX-XX) +Changes in RiotX 0.20.0 (2020-05-15) =================================================== Features ✨: @@ -15,17 +15,8 @@ Bugfix 🐛: - Random Crashes while doing sth with cross signing keys (#1364) - Crash | crash while restoring key backup (#1366) -Translations 🗣: - - - SDK API changes ⚠️: - - excludedUserIds parameter add to to UserService.getPagedUsersLive() function - -Build 🧱: - - - -Other changes: - - + - excludedUserIds parameter added to the UserService.getPagedUsersLive() function Changes in RiotX 0.19.0 (2020-05-04) =================================================== From 48e58967b20b6a4e1990b156aaa48ab20bfe3f54 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 15:48:15 +0200 Subject: [PATCH 114/199] Version++ --- CHANGES.md | 24 ++++++++++++++++++++++++ vector/build.gradle | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 869b034f45..099e4cf5f4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,27 @@ +Changes in RiotX 0.21.0 (2020-XX-XX) +=================================================== + +Features ✨: + - + +Improvements 🙌: + - + +Bugfix 🐛: + - + +Translations 🗣: + - + +SDK API changes ⚠️: + - + +Build 🧱: + - + +Other changes: + - + Changes in RiotX 0.20.0 (2020-05-15) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index 459b297fd6..74fc96a425 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -15,7 +15,7 @@ androidExtensions { } ext.versionMajor = 0 -ext.versionMinor = 20 +ext.versionMinor = 21 ext.versionPatch = 0 static def getGitTimestamp() { From 5fa247a0c5c02e34ea2caf6b68e458b115eb21ce Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 15:50:15 +0200 Subject: [PATCH 115/199] Remove temporary tool and strings_riotX.xml temporary files --- .../src/main/res/values/strings_RiotX.xml | 32 ----- tools/import_from_riot.sh | 122 ------------------ vector/src/main/res/values/strings.xml | 8 ++ vector/src/main/res/values/strings_riotX.xml | 68 ---------- 4 files changed, 8 insertions(+), 222 deletions(-) delete mode 100644 matrix-sdk-android/src/main/res/values/strings_RiotX.xml delete mode 100755 tools/import_from_riot.sh delete mode 100644 vector/src/main/res/values/strings_riotX.xml diff --git a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml b/matrix-sdk-android/src/main/res/values/strings_RiotX.xml deleted file mode 100644 index 6eb46fd7df..0000000000 --- a/matrix-sdk-android/src/main/res/values/strings_RiotX.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - diff --git a/tools/import_from_riot.sh b/tools/import_from_riot.sh deleted file mode 100755 index a2b68a347c..0000000000 --- a/tools/import_from_riot.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env bash - -# -# Copyright 2018 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. -# - -# Exit on any error -set -e - -echo -echo "Copy strings to SDK" - -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values/strings.xml ./matrix-sdk-android/src/main/res/values/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-ar/strings.xml ./matrix-sdk-android/src/main/res/values-ar/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-az/strings.xml ./matrix-sdk-android/src/main/res/values-az/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-bg/strings.xml ./matrix-sdk-android/src/main/res/values-bg/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-bs/strings.xml ./matrix-sdk-android/src/main/res/values-bs/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-ca/strings.xml ./matrix-sdk-android/src/main/res/values-ca/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-cs/strings.xml ./matrix-sdk-android/src/main/res/values-cs/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-da/strings.xml ./matrix-sdk-android/src/main/res/values-da/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-de/strings.xml ./matrix-sdk-android/src/main/res/values-de/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-el/strings.xml ./matrix-sdk-android/src/main/res/values-el/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-eo/strings.xml ./matrix-sdk-android/src/main/res/values-eo/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-en-rGB/strings.xml ./matrix-sdk-android/src/main/res/values-en-rGB/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es/strings.xml ./matrix-sdk-android/src/main/res/values-es/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-es-rMX/strings.xml ./matrix-sdk-android/src/main/res/values-es-rMX/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-eu/strings.xml ./matrix-sdk-android/src/main/res/values-eu/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fa/strings.xml ./matrix-sdk-android/src/main/res/values-fa/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fi/strings.xml ./matrix-sdk-android/src/main/res/values-fi/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-fr/strings.xml ./matrix-sdk-android/src/main/res/values-fr/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-gl/strings.xml ./matrix-sdk-android/src/main/res/values-gl/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-hu/strings.xml ./matrix-sdk-android/src/main/res/values-hu/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-id/strings.xml ./matrix-sdk-android/src/main/res/values-id/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-in/strings.xml ./matrix-sdk-android/src/main/res/values-in/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-is/strings.xml ./matrix-sdk-android/src/main/res/values-is/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-it/strings.xml ./matrix-sdk-android/src/main/res/values-it/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-ja/strings.xml ./matrix-sdk-android/src/main/res/values-ja/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-ko/strings.xml ./matrix-sdk-android/src/main/res/values-ko/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-lv/strings.xml ./matrix-sdk-android/src/main/res/values-lv/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-nl/strings.xml ./matrix-sdk-android/src/main/res/values-nl/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-nn/strings.xml ./matrix-sdk-android/src/main/res/values-nn/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-pl/strings.xml ./matrix-sdk-android/src/main/res/values-pl/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-pt/strings.xml ./matrix-sdk-android/src/main/res/values-pt/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-pt-rBR/strings.xml ./matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-ru/strings.xml ./matrix-sdk-android/src/main/res/values-ru/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-sk/strings.xml ./matrix-sdk-android/src/main/res/values-sk/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-sq/strings.xml ./matrix-sdk-android/src/main/res/values-sq/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-te/strings.xml ./matrix-sdk-android/src/main/res/values-te/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-th/strings.xml ./matrix-sdk-android/src/main/res/values-th/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-uk/strings.xml ./matrix-sdk-android/src/main/res/values-uk/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-vls/strings.xml ./matrix-sdk-android/src/main/res/values-vls/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-zh-rCN/strings.xml ./matrix-sdk-android/src/main/res/values-zh-rCN/strings.xml -cp ../matrix-android-sdk/matrix-sdk/src/main/res/values-zh-rTW/strings.xml ./matrix-sdk-android/src/main/res/values-zh-rTW/strings.xml - -echo -echo "Copy strings to RiotX" - -cp ../riot-android/vector/src/main/res/values/strings.xml ./vector/src/main/res/values/strings.xml -cp ../riot-android/vector/src/main/res/values-ar/strings.xml ./vector/src/main/res/values-ar/strings.xml -cp ../riot-android/vector/src/main/res/values-az/strings.xml ./vector/src/main/res/values-az/strings.xml -cp ../riot-android/vector/src/main/res/values-b+sr+Latn/strings.xml ./vector/src/main/res/values-b+sr+Latn/strings.xml -cp ../riot-android/vector/src/main/res/values-bg/strings.xml ./vector/src/main/res/values-bg/strings.xml -cp ../riot-android/vector/src/main/res/values-bn-rIN/strings.xml ./vector/src/main/res/values-bn-rIN/strings.xml -cp ../riot-android/vector/src/main/res/values-bs/strings.xml ./vector/src/main/res/values-bs/strings.xml -cp ../riot-android/vector/src/main/res/values-ca/strings.xml ./vector/src/main/res/values-ca/strings.xml -cp ../riot-android/vector/src/main/res/values-cs/strings.xml ./vector/src/main/res/values-cs/strings.xml -cp ../riot-android/vector/src/main/res/values-cy/strings.xml ./vector/src/main/res/values-cy/strings.xml -cp ../riot-android/vector/src/main/res/values-da/strings.xml ./vector/src/main/res/values-da/strings.xml -cp ../riot-android/vector/src/main/res/values-de/strings.xml ./vector/src/main/res/values-de/strings.xml -cp ../riot-android/vector/src/main/res/values-el/strings.xml ./vector/src/main/res/values-el/strings.xml -cp ../riot-android/vector/src/main/res/values-eo/strings.xml ./vector/src/main/res/values-eo/strings.xml -cp ../riot-android/vector/src/main/res/values-es/strings.xml ./vector/src/main/res/values-es/strings.xml -cp ../riot-android/vector/src/main/res/values-es-rMX/strings.xml ./vector/src/main/res/values-es-rMX/strings.xml -cp ../riot-android/vector/src/main/res/values-eu/strings.xml ./vector/src/main/res/values-eu/strings.xml -cp ../riot-android/vector/src/main/res/values-fa/strings.xml ./vector/src/main/res/values-fa/strings.xml -cp ../riot-android/vector/src/main/res/values-fi/strings.xml ./vector/src/main/res/values-fi/strings.xml -cp ../riot-android/vector/src/main/res/values-fy/strings.xml ./vector/src/main/res/values-fy/strings.xml -cp ../riot-android/vector/src/main/res/values-fr/strings.xml ./vector/src/main/res/values-fr/strings.xml -cp ../riot-android/vector/src/main/res/values-fr-rCA/strings.xml ./vector/src/main/res/values-fr-rCA/strings.xml -cp ../riot-android/vector/src/main/res/values-gl/strings.xml ./vector/src/main/res/values-gl/strings.xml -cp ../riot-android/vector/src/main/res/values-hu/strings.xml ./vector/src/main/res/values-hu/strings.xml -cp ../riot-android/vector/src/main/res/values-id/strings.xml ./vector/src/main/res/values-id/strings.xml -cp ../riot-android/vector/src/main/res/values-in/strings.xml ./vector/src/main/res/values-in/strings.xml -cp ../riot-android/vector/src/main/res/values-is/strings.xml ./vector/src/main/res/values-is/strings.xml -cp ../riot-android/vector/src/main/res/values-it/strings.xml ./vector/src/main/res/values-it/strings.xml -cp ../riot-android/vector/src/main/res/values-ja/strings.xml ./vector/src/main/res/values-ja/strings.xml -cp ../riot-android/vector/src/main/res/values-ko/strings.xml ./vector/src/main/res/values-ko/strings.xml -cp ../riot-android/vector/src/main/res/values-lv/strings.xml ./vector/src/main/res/values-lv/strings.xml -cp ../riot-android/vector/src/main/res/values-nb-rNO/strings.xml ./vector/src/main/res/values-nb-rNO/strings.xml -cp ../riot-android/vector/src/main/res/values-nl/strings.xml ./vector/src/main/res/values-nl/strings.xml -cp ../riot-android/vector/src/main/res/values-nn/strings.xml ./vector/src/main/res/values-nn/strings.xml -cp ../riot-android/vector/src/main/res/values-pl/strings.xml ./vector/src/main/res/values-pl/strings.xml -cp ../riot-android/vector/src/main/res/values-pt/strings.xml ./vector/src/main/res/values-pt/strings.xml -cp ../riot-android/vector/src/main/res/values-pt-rBR/strings.xml ./vector/src/main/res/values-pt-rBR/strings.xml -cp ../riot-android/vector/src/main/res/values-ro/strings.xml ./vector/src/main/res/values-ro/strings.xml -cp ../riot-android/vector/src/main/res/values-ru/strings.xml ./vector/src/main/res/values-ru/strings.xml -cp ../riot-android/vector/src/main/res/values-sk/strings.xml ./vector/src/main/res/values-sk/strings.xml -cp ../riot-android/vector/src/main/res/values-sq/strings.xml ./vector/src/main/res/values-sq/strings.xml -cp ../riot-android/vector/src/main/res/values-sr/strings.xml ./vector/src/main/res/values-sr/strings.xml -cp ../riot-android/vector/src/main/res/values-te/strings.xml ./vector/src/main/res/values-te/strings.xml -cp ../riot-android/vector/src/main/res/values-th/strings.xml ./vector/src/main/res/values-th/strings.xml -cp ../riot-android/vector/src/main/res/values-tlh/strings.xml ./vector/src/main/res/values-tlh/strings.xml -cp ../riot-android/vector/src/main/res/values-tr/strings.xml ./vector/src/main/res/values-tr/strings.xml -cp ../riot-android/vector/src/main/res/values-uk/strings.xml ./vector/src/main/res/values-uk/strings.xml -cp ../riot-android/vector/src/main/res/values-vls/strings.xml ./vector/src/main/res/values-vls/strings.xml -cp ../riot-android/vector/src/main/res/values-zh-rCN/strings.xml ./vector/src/main/res/values-zh-rCN/strings.xml -cp ../riot-android/vector/src/main/res/values-zh-rTW/strings.xml ./vector/src/main/res/values-zh-rTW/strings.xml - -echo -echo "Success!" diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ff821f5b95..89cbc9a856 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1939,6 +1939,14 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming Too many requests have been sent. You can retry in %1$d seconds… + Alternatively, if you already have an account and you know your Matrix identifier and your password, you can use this method: + Sign in with my Matrix identifier + Sign in + Enter your identifier and your password + User identifier + This is not a valid user identifier. Expected format: \'@user:homeserver.org\' + Unable to find a valid homeserver. Please check your identifier + Seen by You’re signed out diff --git a/vector/src/main/res/values/strings_riotX.xml b/vector/src/main/res/values/strings_riotX.xml deleted file mode 100644 index dd1043819d..0000000000 --- a/vector/src/main/res/values/strings_riotX.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Alternatively, if you already have an account and you know your Matrix identifier and your password, you can use this method: - Sign in with my Matrix identifier - Sign in - Enter your identifier and your password - User identifier - This is not a valid user identifier. Expected format: \'@user:homeserver.org\' - Unable to find a valid homeserver. Please check your identifier - - From 3185b88fe525bc20a7bb86614bbba38b46d4acd9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 09:34:14 +0200 Subject: [PATCH 116/199] Better connectivity lost indicator when airplane mode is on --- CHANGES.md | 2 +- .../java/im/vector/riotx/core/utils/SystemUtils.kt | 4 ++++ .../riotx/features/sync/widget/SyncStateView.kt | 14 ++++++++++---- vector/src/main/res/layout/view_sync_state.xml | 13 +++++++++++++ vector/src/main/res/values/strings.xml | 1 + 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 099e4cf5f4..37cdfba1f5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - Better connectivity lost indicator when airplane mode is on Bugfix 🐛: - diff --git a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt index d82134caf5..23f3cbc875 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt @@ -53,6 +53,10 @@ fun isIgnoringBatteryOptimizations(context: Context): Boolean { || (context.getSystemService(Context.POWER_SERVICE) as PowerManager?)?.isIgnoringBatteryOptimizations(context.packageName) == true } +fun isAirplaneModeOn(context: Context): Boolean { + return Settings.Global.getInt(context.contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0 +} + /** * display the system dialog for granting this permission. If previously granted, the * system will not show it (so you should call this method). diff --git a/vector/src/main/java/im/vector/riotx/features/sync/widget/SyncStateView.kt b/vector/src/main/java/im/vector/riotx/features/sync/widget/SyncStateView.kt index b8856dddb1..fa392a10ad 100755 --- a/vector/src/main/java/im/vector/riotx/features/sync/widget/SyncStateView.kt +++ b/vector/src/main/java/im/vector/riotx/features/sync/widget/SyncStateView.kt @@ -23,6 +23,7 @@ import android.widget.FrameLayout import androidx.core.view.isVisible import im.vector.matrix.android.api.session.sync.SyncState import im.vector.riotx.R +import im.vector.riotx.core.utils.isAirplaneModeOn import kotlinx.android.synthetic.main.view_sync_state.view.* class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) @@ -33,10 +34,15 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute } fun render(newState: SyncState) { - syncStateProgressBar.visibility = when (newState) { - is SyncState.Running -> if (newState.afterPause) View.VISIBLE else View.GONE - else -> View.GONE + syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause + + if (newState == SyncState.NoNetwork) { + val isAirplaneModeOn = isAirplaneModeOn(context) + syncStateNoNetwork.isVisible = isAirplaneModeOn.not() + syncStateNoNetworkAirplane.isVisible = isAirplaneModeOn + } else { + syncStateNoNetwork.isVisible = false + syncStateNoNetworkAirplane.isVisible = false } - syncStateNoNetwork.isVisible = newState == SyncState.NoNetwork } } diff --git a/vector/src/main/res/layout/view_sync_state.xml b/vector/src/main/res/layout/view_sync_state.xml index bc828045fe..0e7ddabc21 100644 --- a/vector/src/main/res/layout/view_sync_state.xml +++ b/vector/src/main/res/layout/view_sync_state.xml @@ -33,6 +33,19 @@ android:text="@string/no_connectivity_to_the_server_indicator" android:textColor="@color/white" android:visibility="gone" + tools:layout_marginTop="10dp" + tools:visibility="visible" /> + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 89cbc9a856..0158c61fcc 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2163,6 +2163,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming No Connectivity to the server has been lost + Airplane mode is on Dev Tools Account Data From 9fed62e4a7aa80a34846fdd289056bc1e9288041 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 01:31:15 +0200 Subject: [PATCH 117/199] Improve template --- .../RiotXFeature/root/src/app_package/ViewModel.kt.ftl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl b/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl index f4090b40e6..1d2ec0a069 100644 --- a/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl +++ b/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl @@ -6,6 +6,7 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject +import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.platform.VectorViewModel <#if createViewEvents> @@ -38,7 +39,8 @@ class ${viewModelClass} @AssistedInject constructor(@Assisted initialState: ${vi } override fun handle(action: ${actionClass}) { - //TODO - } + when (action) { + }.exhaustive + } } From f45040c4051f602ef8207fdcf69ee2135e37ad9e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 02:14:12 +0200 Subject: [PATCH 118/199] Locale: support locale change --- CHANGES.md | 2 +- .../im/vector/riotx/core/di/FragmentModule.kt | 10 ++- .../vector/riotx/core/extensions/Activity.kt | 6 ++ .../configuration/VectorConfiguration.kt | 2 - .../riotx/features/settings/VectorLocale.kt | 41 ++++++---- .../VectorSettingsPreferencesFragment.kt | 26 ------ .../features/settings/locale/LocaleItem.kt | 48 +++++++++++ .../settings/locale/LocalePickerAction.kt | 24 ++++++ .../settings/locale/LocalePickerController.kt | 82 +++++++++++++++++++ .../settings/locale/LocalePickerFragment.kt | 80 ++++++++++++++++++ .../settings/locale/LocalePickerViewEvents.kt | 23 ++++++ .../settings/locale/LocalePickerViewModel.kt | 68 +++++++++++++++ .../settings/locale/LocalePickerViewState.kt | 25 ++++++ .../res/layout/fragment_locale_picker.xml | 8 ++ vector/src/main/res/layout/item_locale.xml | 41 ++++++++++ vector/src/main/res/values/strings.xml | 3 + .../res/xml/vector_settings_preferences.xml | 5 +- 17 files changed, 444 insertions(+), 50 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocaleItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerAction.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerFragment.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewEvents.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt create mode 100644 vector/src/main/res/layout/fragment_locale_picker.xml create mode 100644 vector/src/main/res/layout/item_locale.xml diff --git a/CHANGES.md b/CHANGES.md index 37cdfba1f5..0ff37419cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ Changes in RiotX 0.21.0 (2020-XX-XX) =================================================== Features ✨: - - + - Switch language support (#41) Improvements 🙌: - Better connectivity lost indicator when airplane mode is on diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt index 01709efcac..26a5142961 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -61,8 +61,6 @@ import im.vector.riotx.features.login.LoginSplashFragment import im.vector.riotx.features.login.LoginWaitForEmailFragment import im.vector.riotx.features.login.LoginWebFragment import im.vector.riotx.features.login.terms.LoginTermsFragment -import im.vector.riotx.features.userdirectory.KnownUsersFragment -import im.vector.riotx.features.userdirectory.UserDirectoryFragment import im.vector.riotx.features.qrcode.QrCodeScannerFragment import im.vector.riotx.features.reactions.EmojiChooserFragment import im.vector.riotx.features.reactions.EmojiSearchResultFragment @@ -92,9 +90,12 @@ import im.vector.riotx.features.settings.devtools.IncomingKeyRequestListFragment import im.vector.riotx.features.settings.devtools.KeyRequestsFragment import im.vector.riotx.features.settings.devtools.OutgoingKeyRequestListFragment import im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment +import im.vector.riotx.features.settings.locale.LocalePickerFragment import im.vector.riotx.features.settings.push.PushGatewaysFragment import im.vector.riotx.features.share.IncomingShareFragment import im.vector.riotx.features.signout.soft.SoftLogoutFragment +import im.vector.riotx.features.userdirectory.KnownUsersFragment +import im.vector.riotx.features.userdirectory.UserDirectoryFragment @Module interface FragmentModule { @@ -109,6 +110,11 @@ interface FragmentModule { @FragmentKey(RoomListFragment::class) fun bindRoomListFragment(fragment: RoomListFragment): Fragment + @Binds + @IntoMap + @FragmentKey(LocalePickerFragment::class) + fun bindLocalePickerFragment(fragment: LocalePickerFragment): Fragment + @Binds @IntoMap @FragmentKey(GroupListFragment::class) diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt index f9f5d3b3d2..b74f143e17 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt @@ -16,6 +16,7 @@ package im.vector.riotx.core.extensions +import android.app.Activity import android.os.Parcelable import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction @@ -59,3 +60,8 @@ fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fun VectorBaseActivity.hideKeyboard() { currentFocus?.hideKeyboard() } + +fun Activity.restart() { + startActivity(intent) + finish() +} diff --git a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt index a4b7ca263d..8ea17fecf6 100644 --- a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt @@ -30,7 +30,6 @@ import javax.inject.Inject /** * Handle locale configuration change, such as theme, font size and locale chosen by the user */ - class VectorConfiguration @Inject constructor(private val context: Context) { // TODO Import mLanguageReceiver From Riot? @@ -98,7 +97,6 @@ class VectorConfiguration @Inject constructor(private val context: Context) { * * @param locale */ - // TODO Call from LanguagePickerActivity fun updateApplicationLocale(locale: Locale) { updateApplicationSettings(locale, FontScale.getFontScalePrefValue(context), ThemeUtils.getApplicationTheme(context)) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index e1a89ab3c4..4d78a30718 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -19,9 +19,8 @@ package im.vector.riotx.features.settings import android.content.Context import android.content.res.Configuration import android.os.Build -import androidx.preference.PreferenceManager import androidx.core.content.edit -import im.vector.riotx.BuildConfig +import androidx.preference.PreferenceManager import im.vector.riotx.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope @@ -75,7 +74,7 @@ object VectorLocale { saveApplicationLocale(context, applicationLocale) } - // init the known locales in background, using kotlin coroutines + // init the known locales in background GlobalScope.launch(Dispatchers.IO) { initApplicationLocales(context) } @@ -144,6 +143,7 @@ object VectorLocale { } else { val resources = context.resources val conf = resources.configuration + @Suppress("DEPRECATION") val savedLocale = conf.locale @Suppress("DEPRECATION") @@ -235,22 +235,29 @@ object VectorLocale { append(locale.getDisplayCountry(locale)) append(")") } + } + } - // In debug mode, also display information about the locale in the current locale. - if (BuildConfig.DEBUG) { - append("\n[") - append(locale.displayLanguage) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && locale.script != "Latn") { - append(" - ") - append(locale.displayScript) - } - if (locale.displayCountry.isNotEmpty()) { - append(" (") - append(locale.displayCountry) - append(")") - } - append("]") + /** + * Information about the locale in the current locale + * + * @param locale the locale to get info from + * @return the string + */ + fun localeToLocalisedStringInfo(locale: Locale): String { + return buildString { + append("[") + append(locale.displayLanguage) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && locale.script != "Latn") { + append(" - ") + append(locale.displayScript) } + if (locale.displayCountry.isNotEmpty()) { + append(" (") + append(locale.displayCountry) + append(")") + } + append("]") } } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt index 9c240ad093..a8ba7bcbe6 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt @@ -18,7 +18,6 @@ package im.vector.riotx.features.settings import android.app.Activity import android.content.Context -import android.content.Intent import android.widget.CheckedTextView import android.widget.LinearLayout import androidx.appcompat.app.AlertDialog @@ -129,21 +128,6 @@ class VectorSettingsPreferencesFragment @Inject constructor( } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - if (resultCode == Activity.RESULT_OK) { - when (requestCode) { - REQUEST_LOCALE -> { - activity?.let { - startActivity(it.intent) - it.finish() - } - } - } - } - } - // ============================================================================================================== // user interface management // ============================================================================================================== @@ -152,12 +136,6 @@ class VectorSettingsPreferencesFragment @Inject constructor( // Selected language selectedLanguagePreference.summary = VectorLocale.localeToLocalisedString(VectorLocale.applicationLocale) - selectedLanguagePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener { - notImplemented() - // TODO startActivityForResult(LanguagePickerActivity.getIntent(activity), REQUEST_LOCALE) - true - } - // Text size textSizePreference.summary = FontScale.getFontScaleDescription(activity!!) @@ -199,8 +177,4 @@ class VectorSettingsPreferencesFragment @Inject constructor( } } } - - companion object { - private const val REQUEST_LOCALE = 777 - } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocaleItem.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocaleItem.kt new file mode 100644 index 0000000000..18c5cb2aae --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocaleItem.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.ClickListener +import im.vector.riotx.core.epoxy.VectorEpoxyHolder +import im.vector.riotx.core.epoxy.VectorEpoxyModel +import im.vector.riotx.core.epoxy.onClick +import im.vector.riotx.core.extensions.setTextOrHide + +@EpoxyModelClass(layout = R.layout.item_locale) +abstract class LocaleItem : VectorEpoxyModel() { + + @EpoxyAttribute var title: String? = null + @EpoxyAttribute var subtitle: String? = null + @EpoxyAttribute var clickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + + holder.view.onClick { clickListener?.invoke() } + holder.titleView.setTextOrHide(title) + holder.subtitleView.setTextOrHide(subtitle) + } + + class Holder : VectorEpoxyHolder() { + val titleView by bind(R.id.localeTitle) + val subtitleView by bind(R.id.localeSubtitle) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerAction.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerAction.kt new file mode 100644 index 0000000000..0bfc203159 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerAction.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import im.vector.riotx.core.platform.VectorViewModelAction +import java.util.Locale + +sealed class LocalePickerAction : VectorViewModelAction { + data class SelectLocale(val locale: Locale) : LocalePickerAction() +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt new file mode 100644 index 0000000000..74c5adf98c --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.noResultItem +import im.vector.riotx.core.epoxy.profiles.profileSectionItem +import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.settings.VectorLocale +import im.vector.riotx.features.settings.VectorPreferences +import java.util.Locale +import javax.inject.Inject + +class LocalePickerController @Inject constructor( + private val vectorPreferences: VectorPreferences, + private val stringProvider: StringProvider +) : TypedEpoxyController() { + + var listener: Listener? = null + + @ExperimentalStdlibApi + override fun buildModels(data: LocalePickerViewState?) { + val list = data?.locales ?: return + + if (list.isEmpty()) { + noResultItem { + id("noResult") + text(stringProvider.getString(R.string.no_result_placeholder)) + } + } else { + profileSectionItem { + id("currentTitle") + title(stringProvider.getString(R.string.choose_locale_current_locale_title)) + } + localeItem { + id(data.currentLocale.toString()) + title(VectorLocale.localeToLocalisedString(data.currentLocale).capitalize(data.currentLocale)) + if (vectorPreferences.developerMode()) { + subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale)) + } + clickListener { listener?.onUseCurrentClicked() } + } + profileSectionItem { + id("otherTitle") + title(stringProvider.getString(R.string.choose_locale_other_locales_title)) + } + list + .filter { it != data.currentLocale } + .sortedBy { VectorLocale.localeToLocalisedString(it).toLowerCase(it) } + .forEach { + localeItem { + id(it.toString()) + title(VectorLocale.localeToLocalisedString(it).capitalize(it)) + if (vectorPreferences.developerMode()) { + subtitle(VectorLocale.localeToLocalisedStringInfo(it)) + } + clickListener { listener?.onLocaleClicked(it) } + } + } + } + } + + interface Listener { + fun onUseCurrentClicked() + fun onLocaleClicked(locale: Locale) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerFragment.kt new file mode 100644 index 0000000000..75d758aafa --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerFragment.kt @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import android.os.Bundle +import android.view.View +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.riotx.R +import im.vector.riotx.core.extensions.cleanup +import im.vector.riotx.core.extensions.configureWith +import im.vector.riotx.core.extensions.exhaustive +import im.vector.riotx.core.extensions.restart +import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.core.platform.VectorBaseFragment +import kotlinx.android.synthetic.main.fragment_locale_picker.* +import java.util.Locale +import javax.inject.Inject + +class LocalePickerFragment @Inject constructor( + private val viewModelFactory: LocalePickerViewModel.Factory, + private val controller: LocalePickerController +) : VectorBaseFragment(), LocalePickerViewModel.Factory by viewModelFactory, LocalePickerController.Listener { + + private val viewModel: LocalePickerViewModel by fragmentViewModel() + + override fun getLayoutResId() = R.layout.fragment_locale_picker + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + localeRecyclerView.configureWith(controller) + controller.listener = this + + viewModel.observeViewEvents { + when (it) { + LocalePickerViewEvents.RestartActivity -> { + activity?.restart() + } + }.exhaustive + } + } + + override fun onDestroyView() { + super.onDestroyView() + localeRecyclerView.cleanup() + controller.listener = null + } + + override fun invalidate() = withState(viewModel) { state -> + controller.setData(state) + } + + override fun onUseCurrentClicked() { + // Just close the fragment + parentFragmentManager.popBackStack() + } + + override fun onLocaleClicked(locale: Locale) { + viewModel.handle(LocalePickerAction.SelectLocale(locale)) + } + + override fun onResume() { + super.onResume() + (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_select_language) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewEvents.kt new file mode 100644 index 0000000000..e007f5f036 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewEvents.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import im.vector.riotx.core.platform.VectorViewEvents + +sealed class LocalePickerViewEvents : VectorViewEvents { + object RestartActivity : LocalePickerViewEvents() +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt new file mode 100644 index 0000000000..1adcad5086 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import com.airbnb.mvrx.ActivityViewModelContext +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import im.vector.riotx.core.extensions.exhaustive +import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.features.configuration.VectorConfiguration +import im.vector.riotx.features.settings.VectorLocale + +class LocalePickerViewModel @AssistedInject constructor( + @Assisted initialState: LocalePickerViewState, + private val vectorConfiguration: VectorConfiguration +) : VectorViewModel(initialState) { + + @AssistedInject.Factory + interface Factory { + fun create(initialState: LocalePickerViewState): LocalePickerViewModel + } + + companion object : MvRxViewModelFactory { + + override fun initialState(viewModelContext: ViewModelContext): LocalePickerViewState? { + return LocalePickerViewState( + locales = VectorLocale.supportedLocales + ) + } + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: LocalePickerViewState): LocalePickerViewModel? { + val factory = when (viewModelContext) { + is FragmentViewModelContext -> viewModelContext.fragment as? Factory + is ActivityViewModelContext -> viewModelContext.activity as? Factory + } + return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface") + } + } + + override fun handle(action: LocalePickerAction) { + when (action) { + is LocalePickerAction.SelectLocale -> handleSelectLocale(action) + }.exhaustive + } + + private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) { + vectorConfiguration.updateApplicationLocale(action.locale) + _viewEvents.post(LocalePickerViewEvents.RestartActivity) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt new file mode 100644 index 0000000000..6a0f39ab66 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import com.airbnb.mvrx.MvRxState +import java.util.Locale + +data class LocalePickerViewState( + val currentLocale: Locale = Locale.getDefault(), + val locales: List = emptyList() +) : MvRxState diff --git a/vector/src/main/res/layout/fragment_locale_picker.xml b/vector/src/main/res/layout/fragment_locale_picker.xml new file mode 100644 index 0000000000..1d7977d19a --- /dev/null +++ b/vector/src/main/res/layout/fragment_locale_picker.xml @@ -0,0 +1,8 @@ + + diff --git a/vector/src/main/res/layout/item_locale.xml b/vector/src/main/res/layout/item_locale.xml new file mode 100644 index 0000000000..a446f23e78 --- /dev/null +++ b/vector/src/main/res/layout/item_locale.xml @@ -0,0 +1,41 @@ + + + + + + + + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 0158c61fcc..f2e5ea4edc 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2393,4 +2393,7 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming We could not invite users. Please check the users you want to invite and try again. + Current language + Other available languages + \ No newline at end of file diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index e7217b7394..dde967a283 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -7,9 +7,10 @@ android:title="@string/settings_user_interface"> + android:persistent="false" + android:title="@string/settings_interface_language" + app:fragment="im.vector.riotx.features.settings.locale.LocalePickerFragment" /> Date: Thu, 14 May 2020 11:22:44 +0200 Subject: [PATCH 119/199] FontSize: rework by creating FontScaleValue data class. --- CHANGES.md | 2 +- .../configuration/VectorConfiguration.kt | 24 ++-- .../riotx/features/settings/FontScale.kt | 135 +++++------------- .../VectorSettingsPreferencesFragment.kt | 12 +- .../riotx/features/themes/ThemeUtils.kt | 2 +- .../res/xml/vector_settings_preferences.xml | 1 + 6 files changed, 56 insertions(+), 120 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0ff37419cd..991078e704 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Better connectivity lost indicator when airplane mode is on Bugfix 🐛: - - + - Fix issues with FontScale switch (#69, #645) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt index 8ea17fecf6..d4dfd297b7 100644 --- a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt @@ -38,20 +38,20 @@ class VectorConfiguration @Inject constructor(private val context: Context) { Timber.v("## onConfigurationChanged(): the locale has been updated to ${Locale.getDefault()}") Timber.v("## onConfigurationChanged(): restore the expected value ${VectorLocale.applicationLocale}") updateApplicationSettings(VectorLocale.applicationLocale, - FontScale.getFontScalePrefValue(context), - ThemeUtils.getApplicationTheme(context)) + FontScale.getFontScaleValue(context), + ThemeUtils.getApplicationTheme(context)) } } - private fun updateApplicationSettings(locale: Locale, textSize: String, theme: String) { + private fun updateApplicationSettings(locale: Locale, fontScaleValue: FontScale.FontScaleValue, theme: String) { VectorLocale.saveApplicationLocale(context, locale) - FontScale.saveFontScale(context, textSize) + FontScale.saveFontScaleValue(context, fontScaleValue) Locale.setDefault(locale) val config = Configuration(context.resources.configuration) @Suppress("DEPRECATION") config.locale = locale - config.fontScale = FontScale.getFontScale(context) + config.fontScale = FontScale.getFontScaleValue(context).scale @Suppress("DEPRECATION") context.resources.updateConfiguration(config, context.resources.displayMetrics) @@ -67,8 +67,8 @@ class VectorConfiguration @Inject constructor(private val context: Context) { fun updateApplicationTheme(theme: String) { ThemeUtils.setApplicationTheme(context, theme) updateApplicationSettings(VectorLocale.applicationLocale, - FontScale.getFontScalePrefValue(context), - theme) + FontScale.getFontScaleValue(context), + theme) } /** @@ -77,14 +77,14 @@ class VectorConfiguration @Inject constructor(private val context: Context) { fun initConfiguration() { VectorLocale.init(context) val locale = VectorLocale.applicationLocale - val fontScale = FontScale.getFontScale(context) + val fontScale = FontScale.getFontScaleValue(context) val theme = ThemeUtils.getApplicationTheme(context) Locale.setDefault(locale) val config = Configuration(context.resources.configuration) @Suppress("DEPRECATION") config.locale = locale - config.fontScale = fontScale + config.fontScale = fontScale.scale @Suppress("DEPRECATION") context.resources.updateConfiguration(config, context.resources.displayMetrics) @@ -98,7 +98,7 @@ class VectorConfiguration @Inject constructor(private val context: Context) { * @param locale */ fun updateApplicationLocale(locale: Locale) { - updateApplicationSettings(locale, FontScale.getFontScalePrefValue(context), ThemeUtils.getApplicationTheme(context)) + updateApplicationSettings(locale, FontScale.getFontScaleValue(context), ThemeUtils.getApplicationTheme(context)) } /** @@ -113,7 +113,7 @@ class VectorConfiguration @Inject constructor(private val context: Context) { val resources = context.resources val locale = VectorLocale.applicationLocale val configuration = resources.configuration - configuration.fontScale = FontScale.getFontScale(context) + configuration.fontScale = FontScale.getFontScaleValue(context).scale if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { configuration.setLocale(locale) @@ -143,7 +143,7 @@ class VectorConfiguration @Inject constructor(private val context: Context) { // TODO Create data class for this fun getHash(): String { return (VectorLocale.applicationLocale.toString() - + "_" + FontScale.getFontScalePrefValue(context) + + "_" + FontScale.getFontScaleValue(context).preferenceValue + "_" + ThemeUtils.getApplicationTheme(context)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt b/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt index a9e797ba7a..c538a1ac0c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt @@ -17,7 +17,7 @@ package im.vector.riotx.features.settings import android.content.Context -import android.content.res.Configuration +import androidx.annotation.StringRes import androidx.core.content.edit import androidx.preference.PreferenceManager import im.vector.riotx.R @@ -29,124 +29,59 @@ object FontScale { // Key for the SharedPrefs private const val APPLICATION_FONT_SCALE_KEY = "APPLICATION_FONT_SCALE_KEY" - // Possible values for the SharedPrefs - private const val FONT_SCALE_TINY = "FONT_SCALE_TINY" - private const val FONT_SCALE_SMALL = "FONT_SCALE_SMALL" - private const val FONT_SCALE_NORMAL = "FONT_SCALE_NORMAL" - private const val FONT_SCALE_LARGE = "FONT_SCALE_LARGE" - private const val FONT_SCALE_LARGER = "FONT_SCALE_LARGER" - private const val FONT_SCALE_LARGEST = "FONT_SCALE_LARGEST" - private const val FONT_SCALE_HUGE = "FONT_SCALE_HUGE" - - private val fontScaleToPrefValue = mapOf( - 0.70f to FONT_SCALE_TINY, - 0.85f to FONT_SCALE_SMALL, - 1.00f to FONT_SCALE_NORMAL, - 1.15f to FONT_SCALE_LARGE, - 1.30f to FONT_SCALE_LARGER, - 1.45f to FONT_SCALE_LARGEST, - 1.60f to FONT_SCALE_HUGE + data class FontScaleValue( + val index: Int, + // Possible values for the SharedPrefs + val preferenceValue: String, + val scale: Float, + @StringRes + val nameResId: Int ) - private val prefValueToNameResId = mapOf( - FONT_SCALE_TINY to R.string.tiny, - FONT_SCALE_SMALL to R.string.small, - FONT_SCALE_NORMAL to R.string.normal, - FONT_SCALE_LARGE to R.string.large, - FONT_SCALE_LARGER to R.string.larger, - FONT_SCALE_LARGEST to R.string.largest, - FONT_SCALE_HUGE to R.string.huge + private val fontScaleValues = listOf( + FontScaleValue(0, "FONT_SCALE_TINY", 0.70f, R.string.tiny), + FontScaleValue(1, "FONT_SCALE_SMALL", 0.85f, R.string.small), + FontScaleValue(2, "FONT_SCALE_NORMAL", 1.00f, R.string.normal), + FontScaleValue(3, "FONT_SCALE_LARGE", 1.15f, R.string.large), + FontScaleValue(4, "FONT_SCALE_LARGER", 1.30f, R.string.larger), + FontScaleValue(5, "FONT_SCALE_LARGEST", 1.45f, R.string.largest), + FontScaleValue(6, "FONT_SCALE_HUGE", 1.60f, R.string.huge) ) + private val normalFontScaleValue = fontScaleValues[2] + /** * Get the font scale value from SharedPrefs. Init the SharedPrefs if necessary * - * @return the font scale + * @return the font scale value */ - fun getFontScalePrefValue(context: Context): String { + fun getFontScaleValue(context: Context): FontScaleValue { val preferences = PreferenceManager.getDefaultSharedPreferences(context) - var scalePreferenceValue: String - if (APPLICATION_FONT_SCALE_KEY !in preferences) { + return if (APPLICATION_FONT_SCALE_KEY !in preferences) { val fontScale = context.resources.configuration.fontScale - scalePreferenceValue = FONT_SCALE_NORMAL - - if (fontScaleToPrefValue.containsKey(fontScale)) { - scalePreferenceValue = fontScaleToPrefValue[fontScale] as String - } - - preferences.edit { - putString(APPLICATION_FONT_SCALE_KEY, scalePreferenceValue) - } + (fontScaleValues.firstOrNull { it.scale == fontScale } ?: normalFontScaleValue) + .also { preferences.edit { putString(APPLICATION_FONT_SCALE_KEY, it.preferenceValue) } } } else { - scalePreferenceValue = preferences.getString(APPLICATION_FONT_SCALE_KEY, FONT_SCALE_NORMAL)!! + val pref = preferences.getString(APPLICATION_FONT_SCALE_KEY, null) + fontScaleValues.firstOrNull { it.preferenceValue == pref } ?: normalFontScaleValue } + } - return scalePreferenceValue + fun updateFontScale(context: Context, index: Int) { + fontScaleValues.getOrNull(index)?.let { + saveFontScaleValue(context, it) + } } /** - * Provides the font scale value + * Store the font scale vale * - * @return the font scale + * @param fontScaleValue the font scale value to store */ - fun getFontScale(context: Context): Float { - val fontScale = getFontScalePrefValue(context) - - if (fontScaleToPrefValue.containsValue(fontScale)) { - for ((key, value) in fontScaleToPrefValue) { - if (value == fontScale) { - return key - } - } - } - - return 1.0f - } - - /** - * Provides the font scale description - * - * @return the font description - */ - fun getFontScaleDescription(context: Context): String { - val fontScale = getFontScalePrefValue(context) - - return if (prefValueToNameResId.containsKey(fontScale)) { - context.getString(prefValueToNameResId[fontScale] as Int) - } else context.getString(R.string.normal) - } - - /** - * Update the font size from the locale description. - * - * @param fontScaleDescription the font scale description - */ - fun updateFontScale(context: Context, fontScaleDescription: String) { - for ((key, value) in prefValueToNameResId) { - if (context.getString(value) == fontScaleDescription) { - saveFontScale(context, key) - } - } - - val config = Configuration(context.resources.configuration) - config.fontScale = getFontScale(context) - @Suppress("DEPRECATION") - context.resources.updateConfiguration(config, context.resources.displayMetrics) - } - - /** - * Save the new font scale - * - * @param scaleValue the text scale - */ - fun saveFontScale(context: Context, scaleValue: String) { - if (scaleValue.isNotEmpty()) { - PreferenceManager.getDefaultSharedPreferences(context) - .edit { - putString(APPLICATION_FONT_SCALE_KEY, scaleValue) - } - } + fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) { + PreferenceManager.getDefaultSharedPreferences(context) + .edit { putString(APPLICATION_FONT_SCALE_KEY, fontScaleValue.preferenceValue) } } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt index a8ba7bcbe6..86a256a2b4 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt @@ -24,6 +24,7 @@ import androidx.appcompat.app.AlertDialog import androidx.preference.Preference import androidx.preference.SwitchPreference import im.vector.riotx.R +import im.vector.riotx.core.extensions.restart import im.vector.riotx.core.preference.VectorListPreference import im.vector.riotx.core.preference.VectorPreference import im.vector.riotx.features.configuration.VectorConfiguration @@ -137,7 +138,7 @@ class VectorSettingsPreferencesFragment @Inject constructor( selectedLanguagePreference.summary = VectorLocale.localeToLocalisedString(VectorLocale.applicationLocale) // Text size - textSizePreference.summary = FontScale.getFontScaleDescription(activity!!) + textSizePreference.summary = getString(FontScale.getFontScaleValue(activity!!).nameResId) textSizePreference.onPreferenceClickListener = Preference.OnPreferenceClickListener { activity?.let { displayTextSizeSelection(it) } @@ -160,19 +161,18 @@ class VectorSettingsPreferencesFragment @Inject constructor( val childCount = linearLayout.childCount - val scaleText = FontScale.getFontScaleDescription(activity) + val index = FontScale.getFontScaleValue(activity).index for (i in 0 until childCount) { val v = linearLayout.getChildAt(i) if (v is CheckedTextView) { - v.isChecked = v.text == scaleText + v.isChecked = i == index v.setOnClickListener { dialog.dismiss() - FontScale.updateFontScale(activity, v.text.toString()) - activity.startActivity(activity.intent) - activity.finish() + FontScale.updateFontScale(activity, i) + activity.restart() } } } diff --git a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt index 1f835164db..45e64465d6 100644 --- a/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/riotx/features/themes/ThemeUtils.kt @@ -52,7 +52,7 @@ object ThemeUtils { */ fun getApplicationTheme(context: Context): String { return PreferenceManager.getDefaultSharedPreferences(context) - .getString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE)!! + .getString(APPLICATION_THEME_KEY, THEME_LIGHT_VALUE) ?: THEME_LIGHT_VALUE } /** diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index dde967a283..b1bd6ea5e6 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -24,6 +24,7 @@ From 19d655ec4149cce0f8bbbf6b23706bec5273cbc4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 11:41:42 +0200 Subject: [PATCH 120/199] Locales: improve algo --- .../vector/riotx/features/settings/VectorLocale.kt | 13 ++++++------- .../settings/locale/LocalePickerController.kt | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index 4d78a30718..13e68d83df 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -42,8 +42,7 @@ object VectorLocale { /** * The supported application languages */ - var supportedLocales = ArrayList() - private set + val supportedLocales = mutableListOf() /** * Provides the current application locale @@ -195,9 +194,7 @@ object VectorLocale { ) } - supportedLocales.clear() - - knownLocalesSet.mapTo(supportedLocales) { (language, country, script) -> + val list = knownLocalesSet.map { (language, country, script) -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Locale.Builder() .setLanguage(language) @@ -208,9 +205,11 @@ object VectorLocale { Locale(language, country) } } + // sort by human display names + .sortedBy { localeToLocalisedString(it).toLowerCase(it) } - // sort by human display names - supportedLocales.sortWith(Comparator { lhs, rhs -> localeToLocalisedString(lhs).compareTo(localeToLocalisedString(rhs)) }) + supportedLocales.clear() + supportedLocales.addAll(list) } /** diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt index 74c5adf98c..ecaeac31c1 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt @@ -61,7 +61,6 @@ class LocalePickerController @Inject constructor( } list .filter { it != data.currentLocale } - .sortedBy { VectorLocale.localeToLocalisedString(it).toLowerCase(it) } .forEach { localeItem { id(it.toString()) From 8ac2cb0530f714409575110c587dfc5bfab844e7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 21:10:03 +0200 Subject: [PATCH 121/199] Cleanup --- .../vector/riotx/core/di/VectorComponent.kt | 4 +- .../riotx/core/platform/VectorBaseActivity.kt | 2 +- .../configuration/VectorConfiguration.kt | 43 +------------------ .../setup/KeysBackupSetupStep2Fragment.kt | 8 ++-- .../riotx/features/settings/FontScale.kt | 2 +- .../riotx/features/settings/VectorLocale.kt | 7 ++- .../VectorSettingsPreferencesFragment.kt | 8 +--- .../settings/locale/LocalePickerViewModel.kt | 16 +++---- 8 files changed, 24 insertions(+), 66 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt index 6f864c7f5b..5c5052cf2b 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/VectorComponent.kt @@ -130,9 +130,9 @@ interface VectorComponent { fun emojiDataSource(): EmojiDataSource - fun alertManager() : PopupAlertManager + fun alertManager(): PopupAlertManager - fun reAuthHelper() : ReAuthHelper + fun reAuthHelper(): ReAuthHelper @Component.Factory interface Factory { diff --git a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt index 08cf8e57e1..191f5dbc4c 100644 --- a/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/riotx/core/platform/VectorBaseActivity.kt @@ -179,7 +179,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { } }) - sessionListener = getVectorComponent().sessionListener() + sessionListener = vectorComponent.sessionListener() sessionListener.globalErrorLiveData.observeEvent(this) { handleGlobalError(it) } diff --git a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt index d4dfd297b7..2ef69890ed 100644 --- a/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/riotx/features/configuration/VectorConfiguration.kt @@ -32,45 +32,14 @@ import javax.inject.Inject */ class VectorConfiguration @Inject constructor(private val context: Context) { - // TODO Import mLanguageReceiver From Riot? fun onConfigurationChanged() { if (Locale.getDefault().toString() != VectorLocale.applicationLocale.toString()) { Timber.v("## onConfigurationChanged(): the locale has been updated to ${Locale.getDefault()}") Timber.v("## onConfigurationChanged(): restore the expected value ${VectorLocale.applicationLocale}") - updateApplicationSettings(VectorLocale.applicationLocale, - FontScale.getFontScaleValue(context), - ThemeUtils.getApplicationTheme(context)) + Locale.setDefault(VectorLocale.applicationLocale) } } - private fun updateApplicationSettings(locale: Locale, fontScaleValue: FontScale.FontScaleValue, theme: String) { - VectorLocale.saveApplicationLocale(context, locale) - FontScale.saveFontScaleValue(context, fontScaleValue) - Locale.setDefault(locale) - - val config = Configuration(context.resources.configuration) - @Suppress("DEPRECATION") - config.locale = locale - config.fontScale = FontScale.getFontScaleValue(context).scale - @Suppress("DEPRECATION") - context.resources.updateConfiguration(config, context.resources.displayMetrics) - - ThemeUtils.setApplicationTheme(context, theme) - // TODO PhoneNumberUtils.onLocaleUpdate() - } - - /** - * Update the application theme - * - * @param theme the new theme - */ - fun updateApplicationTheme(theme: String) { - ThemeUtils.setApplicationTheme(context, theme) - updateApplicationSettings(VectorLocale.applicationLocale, - FontScale.getFontScaleValue(context), - theme) - } - /** * Init the configuration from the saved one */ @@ -92,15 +61,6 @@ class VectorConfiguration @Inject constructor(private val context: Context) { ThemeUtils.setApplicationTheme(context, theme) } - /** - * Update the application locale - * - * @param locale - */ - fun updateApplicationLocale(locale: Locale) { - updateApplicationSettings(locale, FontScale.getFontScaleValue(context), ThemeUtils.getApplicationTheme(context)) - } - /** * Compute a localised context * @@ -140,7 +100,6 @@ class VectorConfiguration @Inject constructor(private val context: Context) { * Compute the locale status value * @return the local status value */ - // TODO Create data class for this fun getHash(): String { return (VectorLocale.applicationLocale.toString() + "_" + FontScale.getFontScaleValue(context).preferenceValue diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index 3522c5a752..93d6f43763 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -164,16 +164,16 @@ class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() @OnClick(R.id.keys_backup_setup_step2_button) fun doNext() { when { - viewModel.passphrase.value.isNullOrEmpty() -> { + viewModel.passphrase.value.isNullOrEmpty() -> { viewModel.passphraseError.value = context?.getString(R.string.passphrase_empty_error_message) } viewModel.passphrase.value != viewModel.confirmPassphrase.value -> { viewModel.confirmPassphraseError.value = context?.getString(R.string.passphrase_passphrase_does_not_match) } - viewModel.passwordStrength.value?.score ?: 0 < 4 -> { + viewModel.passwordStrength.value?.score ?: 0 < 4 -> { viewModel.passphraseError.value = context?.getString(R.string.passphrase_passphrase_too_weak) } - else -> { + else -> { viewModel.megolmBackupCreationInfo = null viewModel.prepareRecoveryKey(activity!!, viewModel.passphrase.value) @@ -190,7 +190,7 @@ class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() viewModel.prepareRecoveryKey(activity!!, null) } - else -> { + else -> { // User has entered a passphrase but want to skip this step. viewModel.passphraseError.value = context?.getString(R.string.keys_backup_passphrase_not_empty_error_message) } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt b/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt index c538a1ac0c..47c438695c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/FontScale.kt @@ -80,7 +80,7 @@ object FontScale { * * @param fontScaleValue the font scale value to store */ - fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) { + private fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) { PreferenceManager.getDefaultSharedPreferences(context) .edit { putString(APPLICATION_FONT_SCALE_KEY, fontScaleValue.preferenceValue) } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index 13e68d83df..95b31be317 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -50,10 +50,13 @@ object VectorLocale { var applicationLocale = defaultLocale private set + lateinit var context: Context + /** * Init this object */ fun init(context: Context) { + this.context = context val preferences = PreferenceManager.getDefaultSharedPreferences(context) if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) { @@ -70,7 +73,7 @@ object VectorLocale { applicationLocale = defaultLocale } - saveApplicationLocale(context, applicationLocale) + saveApplicationLocale(applicationLocale) } // init the known locales in background @@ -82,7 +85,7 @@ object VectorLocale { /** * Save the new application locale. */ - fun saveApplicationLocale(context: Context, locale: Locale) { + fun saveApplicationLocale(locale: Locale) { applicationLocale = locale PreferenceManager.getDefaultSharedPreferences(context).edit { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt index 86a256a2b4..6b021d022f 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsPreferencesFragment.kt @@ -54,13 +54,9 @@ class VectorSettingsPreferencesFragment @Inject constructor( findPreference(ThemeUtils.APPLICATION_THEME_KEY)!! .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> if (newValue is String) { - vectorConfiguration.updateApplicationTheme(newValue) + ThemeUtils.setApplicationTheme(requireContext(), newValue) // Restart the Activity - activity?.let { - // Note: recreate does not apply the color correctly - it.startActivity(it.intent) - it.finish() - } + activity?.restart() true } else { false diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt index 1adcad5086..61142b7af5 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt @@ -24,12 +24,10 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.platform.VectorViewModel -import im.vector.riotx.features.configuration.VectorConfiguration import im.vector.riotx.features.settings.VectorLocale class LocalePickerViewModel @AssistedInject constructor( - @Assisted initialState: LocalePickerViewState, - private val vectorConfiguration: VectorConfiguration + @Assisted initialState: LocalePickerViewState ) : VectorViewModel(initialState) { @AssistedInject.Factory @@ -37,13 +35,15 @@ class LocalePickerViewModel @AssistedInject constructor( fun create(initialState: LocalePickerViewState): LocalePickerViewModel } - companion object : MvRxViewModelFactory { - - override fun initialState(viewModelContext: ViewModelContext): LocalePickerViewState? { - return LocalePickerViewState( + init { + setState { + copy( locales = VectorLocale.supportedLocales ) } + } + + companion object : MvRxViewModelFactory { @JvmStatic override fun create(viewModelContext: ViewModelContext, state: LocalePickerViewState): LocalePickerViewModel? { @@ -62,7 +62,7 @@ class LocalePickerViewModel @AssistedInject constructor( } private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) { - vectorConfiguration.updateApplicationLocale(action.locale) + VectorLocale.saveApplicationLocale(action.locale) _viewEvents.post(LocalePickerViewEvents.RestartActivity) } } From a00ddca188890b660c58315e70416deb71748b60 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 22:04:50 +0200 Subject: [PATCH 122/199] Create SystemLocaleProvider --- .../im/vector/riotx/core/utils/SystemUtils.kt | 21 --------- .../riotx/features/rageshake/BugReporter.kt | 15 ++++--- .../settings/locale/LocalePickerController.kt | 2 +- .../settings/locale/LocalePickerViewState.kt | 3 +- .../settings/locale/SystemLocaleProvider.kt | 44 +++++++++++++++++++ 5 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/settings/locale/SystemLocaleProvider.kt diff --git a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt index 23f3cbc875..9e5af038ef 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/SystemUtils.kt @@ -33,9 +33,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import im.vector.riotx.R import im.vector.riotx.features.notifications.NotificationUtils -import im.vector.riotx.features.settings.VectorLocale -import timber.log.Timber -import java.util.Locale /** * Tells if the application ignores battery optimizations. @@ -94,24 +91,6 @@ fun copyToClipboard(context: Context, text: CharSequence, showToast: Boolean = t } } -/** - * Provides the device locale - * - * @return the device locale - */ -fun getDeviceLocale(context: Context): Locale { - return try { - val packageManager = context.packageManager - val resources = packageManager.getResourcesForApplication("android") - @Suppress("DEPRECATION") - resources.configuration.locale - } catch (e: Exception) { - Timber.e(e, "## getDeviceLocale() failed") - // Fallback to application locale - VectorLocale.applicationLocale - } -} - /** * Shows notification settings for the current app. * In android O will directly opens the notification settings, in lower version it will show the App settings diff --git a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt index 7d58c4aacc..8515a5ac50 100755 --- a/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/riotx/features/rageshake/BugReporter.kt @@ -31,9 +31,9 @@ import im.vector.riotx.BuildConfig import im.vector.riotx.R import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.extensions.toOnOff -import im.vector.riotx.core.utils.getDeviceLocale import im.vector.riotx.features.settings.VectorLocale import im.vector.riotx.features.settings.VectorPreferences +import im.vector.riotx.features.settings.locale.SystemLocaleProvider import im.vector.riotx.features.themes.ThemeUtils import im.vector.riotx.features.version.VersionProvider import okhttp3.Call @@ -58,10 +58,13 @@ import javax.inject.Singleton * BugReporter creates and sends the bug reports. */ @Singleton -class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, - private val versionProvider: VersionProvider, - private val vectorPreferences: VectorPreferences, - private val vectorFileLogger: VectorFileLogger) { +class BugReporter @Inject constructor( + private val activeSessionHolder: ActiveSessionHolder, + private val versionProvider: VersionProvider, + private val vectorPreferences: VectorPreferences, + private val vectorFileLogger: VectorFileLogger, + private val systemLocaleProvider: SystemLocaleProvider +) { var inMultiWindowMode = false companion object { @@ -240,7 +243,7 @@ class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSes + Build.VERSION.INCREMENTAL + "-" + Build.VERSION.CODENAME) .addFormDataPart("locale", Locale.getDefault().toString()) .addFormDataPart("app_language", VectorLocale.applicationLocale.toString()) - .addFormDataPart("default_app_language", getDeviceLocale(context).toString()) + .addFormDataPart("default_app_language", systemLocaleProvider.getSystemLocale().toString()) .addFormDataPart("theme", ThemeUtils.getApplicationTheme(context)) val buildNumber = context.getString(R.string.build_number) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt index ecaeac31c1..3745ba513e 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt @@ -60,7 +60,7 @@ class LocalePickerController @Inject constructor( title(stringProvider.getString(R.string.choose_locale_other_locales_title)) } list - .filter { it != data.currentLocale } + .filter { it.toString() != data.currentLocale.toString() } .forEach { localeItem { id(it.toString()) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt index 6a0f39ab66..e32cdc632c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt @@ -17,9 +17,10 @@ package im.vector.riotx.features.settings.locale import com.airbnb.mvrx.MvRxState +import im.vector.riotx.features.settings.VectorLocale import java.util.Locale data class LocalePickerViewState( - val currentLocale: Locale = Locale.getDefault(), + val currentLocale: Locale = VectorLocale.applicationLocale, val locales: List = emptyList() ) : MvRxState diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/SystemLocaleProvider.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/SystemLocaleProvider.kt new file mode 100644 index 0000000000..d3265f3179 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/SystemLocaleProvider.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.settings.locale + +import android.content.Context +import timber.log.Timber +import java.util.Locale +import javax.inject.Inject + +class SystemLocaleProvider @Inject constructor( + private val context: Context +) { + + /** + * Provides the device locale + * + * @return the device locale, or null in case of error + */ + fun getSystemLocale(): Locale? { + return try { + val packageManager = context.packageManager + val resources = packageManager.getResourcesForApplication("android") + @Suppress("DEPRECATION") + resources.configuration.locale + } catch (e: Exception) { + Timber.e(e, "## getDeviceLocale() failed") + null + } + } +} From 538bda329e78e5309996d91a97370dfeec5ab927 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 May 2020 22:32:47 +0200 Subject: [PATCH 123/199] Lazy load available languages --- .../riotx/features/settings/VectorLocale.kt | 33 ++++++--- .../settings/locale/LocalePickerController.kt | 72 +++++++++++-------- .../settings/locale/LocalePickerViewModel.kt | 27 +++++-- .../settings/locale/LocalePickerViewState.kt | 4 +- vector/src/main/res/values/strings.xml | 1 + 5 files changed, 89 insertions(+), 48 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index 95b31be317..efe4110680 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -24,7 +24,9 @@ import androidx.preference.PreferenceManager import im.vector.riotx.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import timber.log.Timber import java.util.Locale @@ -40,9 +42,9 @@ object VectorLocale { private val defaultLocale = Locale("en", "US") /** - * The supported application languages + * The cache of supported application languages */ - val supportedLocales = mutableListOf() + private val supportedLocales = mutableListOf() /** * Provides the current application locale @@ -75,11 +77,6 @@ object VectorLocale { saveApplicationLocale(applicationLocale) } - - // init the known locales in background - GlobalScope.launch(Dispatchers.IO) { - initApplicationLocales(context) - } } /** @@ -167,11 +164,9 @@ object VectorLocale { } /** - * Provides the supported application locales list - * - * @param context the context + * Init the supported application locales list */ - private fun initApplicationLocales(context: Context) { + private fun initApplicationLocales() { val knownLocalesSet = HashSet>() try { @@ -262,4 +257,20 @@ object VectorLocale { append("]") } } + + fun loadLocales(listener: Listener): Job { + return GlobalScope.launch(Dispatchers.Main) { + if (supportedLocales.isEmpty()) { + // init the known locales in background + withContext(Dispatchers.IO) { + initApplicationLocales() + } + } + listener.onLoaded(supportedLocales) + } + } + + interface Listener { + fun onLoaded(locales: List) + } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt index 3745ba513e..5e6704818f 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerController.kt @@ -17,7 +17,10 @@ package im.vector.riotx.features.settings.locale import com.airbnb.epoxy.TypedEpoxyController +import com.airbnb.mvrx.Incomplete +import com.airbnb.mvrx.Success import im.vector.riotx.R +import im.vector.riotx.core.epoxy.loadingItem import im.vector.riotx.core.epoxy.noResultItem import im.vector.riotx.core.epoxy.profiles.profileSectionItem import im.vector.riotx.core.resources.StringProvider @@ -37,40 +40,49 @@ class LocalePickerController @Inject constructor( override fun buildModels(data: LocalePickerViewState?) { val list = data?.locales ?: return - if (list.isEmpty()) { - noResultItem { - id("noResult") - text(stringProvider.getString(R.string.no_result_placeholder)) + profileSectionItem { + id("currentTitle") + title(stringProvider.getString(R.string.choose_locale_current_locale_title)) + } + localeItem { + id(data.currentLocale.toString()) + title(VectorLocale.localeToLocalisedString(data.currentLocale).capitalize(data.currentLocale)) + if (vectorPreferences.developerMode()) { + subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale)) } - } else { - profileSectionItem { - id("currentTitle") - title(stringProvider.getString(R.string.choose_locale_current_locale_title)) - } - localeItem { - id(data.currentLocale.toString()) - title(VectorLocale.localeToLocalisedString(data.currentLocale).capitalize(data.currentLocale)) - if (vectorPreferences.developerMode()) { - subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale)) + clickListener { listener?.onUseCurrentClicked() } + } + profileSectionItem { + id("otherTitle") + title(stringProvider.getString(R.string.choose_locale_other_locales_title)) + } + when (list) { + is Incomplete -> { + loadingItem { + id("loading") + loadingText(stringProvider.getString(R.string.choose_locale_loading_locales)) } - clickListener { listener?.onUseCurrentClicked() } } - profileSectionItem { - id("otherTitle") - title(stringProvider.getString(R.string.choose_locale_other_locales_title)) - } - list - .filter { it.toString() != data.currentLocale.toString() } - .forEach { - localeItem { - id(it.toString()) - title(VectorLocale.localeToLocalisedString(it).capitalize(it)) - if (vectorPreferences.developerMode()) { - subtitle(VectorLocale.localeToLocalisedStringInfo(it)) - } - clickListener { listener?.onLocaleClicked(it) } - } + is Success -> + if (list().isEmpty()) { + noResultItem { + id("noResult") + text(stringProvider.getString(R.string.no_result_placeholder)) } + } else { + list() + .filter { it.toString() != data.currentLocale.toString() } + .forEach { + localeItem { + id(it.toString()) + title(VectorLocale.localeToLocalisedString(it).capitalize(it)) + if (vectorPreferences.developerMode()) { + subtitle(VectorLocale.localeToLocalisedStringInfo(it)) + } + clickListener { listener?.onLocaleClicked(it) } + } + } + } } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt index 61142b7af5..f0a4243439 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt @@ -19,28 +19,30 @@ package im.vector.riotx.features.settings.locale import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.features.settings.VectorLocale +import kotlinx.coroutines.Job +import java.util.Locale class LocalePickerViewModel @AssistedInject constructor( @Assisted initialState: LocalePickerViewState -) : VectorViewModel(initialState) { +) : VectorViewModel(initialState), + VectorLocale.Listener { @AssistedInject.Factory interface Factory { fun create(initialState: LocalePickerViewState): LocalePickerViewModel } + private var loadingJob: Job? = null + init { - setState { - copy( - locales = VectorLocale.supportedLocales - ) - } + loadingJob = VectorLocale.loadLocales(this) } companion object : MvRxViewModelFactory { @@ -65,4 +67,17 @@ class LocalePickerViewModel @AssistedInject constructor( VectorLocale.saveApplicationLocale(action.locale) _viewEvents.post(LocalePickerViewEvents.RestartActivity) } + + override fun onLoaded(locales: List) { + setState { + copy( + locales = Success(locales) + ) + } + } + + override fun onCleared() { + super.onCleared() + loadingJob?.cancel() + } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt index e32cdc632c..416350d827 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewState.kt @@ -16,11 +16,13 @@ package im.vector.riotx.features.settings.locale +import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized import im.vector.riotx.features.settings.VectorLocale import java.util.Locale data class LocalePickerViewState( val currentLocale: Locale = VectorLocale.applicationLocale, - val locales: List = emptyList() + val locales: Async> = Uninitialized ) : MvRxState diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index f2e5ea4edc..4022b1ef92 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2395,5 +2395,6 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming Current language Other available languages + Loading available languages… \ No newline at end of file From 28f8d9500ee9d88f3280bdf39940d561b5147f0c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 18 May 2020 15:59:15 +0200 Subject: [PATCH 124/199] Better coroutine management --- .../riotx/features/settings/VectorLocale.kt | 21 ++++-------- .../settings/locale/LocalePickerViewModel.kt | 32 +++++++------------ 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt index efe4110680..a4ccfdba47 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorLocale.kt @@ -23,9 +23,6 @@ import androidx.core.content.edit import androidx.preference.PreferenceManager import im.vector.riotx.R import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber import java.util.Locale @@ -258,19 +255,13 @@ object VectorLocale { } } - fun loadLocales(listener: Listener): Job { - return GlobalScope.launch(Dispatchers.Main) { - if (supportedLocales.isEmpty()) { - // init the known locales in background - withContext(Dispatchers.IO) { - initApplicationLocales() - } + suspend fun getSupportedLocales(): List { + if (supportedLocales.isEmpty()) { + // init the known locales in background + withContext(Dispatchers.IO) { + initApplicationLocales() } - listener.onLoaded(supportedLocales) } - } - - interface Listener { - fun onLoaded(locales: List) + return supportedLocales } } diff --git a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt index f0a4243439..e4cc64733c 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/locale/LocalePickerViewModel.kt @@ -16,6 +16,7 @@ package im.vector.riotx.features.settings.locale +import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory @@ -26,23 +27,27 @@ import com.squareup.inject.assisted.AssistedInject import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.features.settings.VectorLocale -import kotlinx.coroutines.Job -import java.util.Locale +import kotlinx.coroutines.launch class LocalePickerViewModel @AssistedInject constructor( @Assisted initialState: LocalePickerViewState -) : VectorViewModel(initialState), - VectorLocale.Listener { +) : VectorViewModel(initialState) { @AssistedInject.Factory interface Factory { fun create(initialState: LocalePickerViewState): LocalePickerViewModel } - private var loadingJob: Job? = null - init { - loadingJob = VectorLocale.loadLocales(this) + viewModelScope.launch { + val result = VectorLocale.getSupportedLocales() + + setState { + copy( + locales = Success(result) + ) + } + } } companion object : MvRxViewModelFactory { @@ -67,17 +72,4 @@ class LocalePickerViewModel @AssistedInject constructor( VectorLocale.saveApplicationLocale(action.locale) _viewEvents.post(LocalePickerViewEvents.RestartActivity) } - - override fun onLoaded(locales: List) { - setState { - copy( - locales = Success(locales) - ) - } - } - - override fun onCleared() { - super.onCleared() - loadingJob?.cancel() - } } From 05d1e64cb5de5cb6dc44cf132c273e295d216ed8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 09:46:39 +0200 Subject: [PATCH 125/199] New rendering for redacted message --- vector/src/main/res/drawable/ic_trash_16.xml | 41 +++++++++++++++++++ vector/src/main/res/drawable/ic_trash_24.xml | 41 +++++++++++++++++++ .../main/res/drawable/redacted_background.xml | 5 --- .../res/layout/item_timeline_event_base.xml | 7 ++-- .../item_timeline_event_redacted_stub.xml | 13 ++++-- vector/src/main/res/values/strings.xml | 1 + 6 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 vector/src/main/res/drawable/ic_trash_16.xml create mode 100644 vector/src/main/res/drawable/ic_trash_24.xml delete mode 100644 vector/src/main/res/drawable/redacted_background.xml diff --git a/vector/src/main/res/drawable/ic_trash_16.xml b/vector/src/main/res/drawable/ic_trash_16.xml new file mode 100644 index 0000000000..ca6052b447 --- /dev/null +++ b/vector/src/main/res/drawable/ic_trash_16.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/vector/src/main/res/drawable/ic_trash_24.xml b/vector/src/main/res/drawable/ic_trash_24.xml new file mode 100644 index 0000000000..266855d50c --- /dev/null +++ b/vector/src/main/res/drawable/ic_trash_24.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/vector/src/main/res/drawable/redacted_background.xml b/vector/src/main/res/drawable/redacted_background.xml deleted file mode 100644 index f253a9eaf7..0000000000 --- a/vector/src/main/res/drawable/redacted_background.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index 3ae80424cc..7cc929306e 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -66,16 +66,15 @@ android:id="@+id/decorationSpace" android:layout_width="4dp" android:layout_height="8dp" - android:layout_toEndOf="@id/messageStartGuideline" - /> + android:layout_toEndOf="@id/messageStartGuideline" /> @@ -119,7 +118,7 @@ diff --git a/vector/src/main/res/layout/item_timeline_event_redacted_stub.xml b/vector/src/main/res/layout/item_timeline_event_redacted_stub.xml index 2f930577f0..acc60e6590 100644 --- a/vector/src/main/res/layout/item_timeline_event_redacted_stub.xml +++ b/vector/src/main/res/layout/item_timeline_event_redacted_stub.xml @@ -1,4 +1,11 @@ - \ No newline at end of file + android:layout_height="wrap_content" + android:drawableStart="@drawable/ic_trash_16" + android:drawablePadding="8dp" + android:gravity="center_vertical" + android:text="@string/event_redacted" + android:textColor="?riotx_text_primary_body_contrast" + android:textSize="14sp" + app:drawableTint="?riotx_text_primary_body_contrast" /> \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 4022b1ef92..f9c45e2236 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1563,6 +1563,7 @@ Why choose Riot.im? View Reactions Reactions + Message deleted Event deleted by user Event moderated by room admin Last edited by %1$s on %2$s From e542e4ba22a7ec70042762ff4d96ba982ff96c37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 May 2020 10:16:01 +0200 Subject: [PATCH 126/199] Add a setting to hide redacted events (#951) --- CHANGES.md | 1 + .../session/room/timeline/TimelineSettings.kt | 4 ++++ .../database/query/UnsignedContent.kt | 21 +++++++++++++++++++ .../session/room/timeline/DefaultTimeline.kt | 12 ++++++++++- .../core/resources/UserPreferencesProvider.kt | 4 ++++ .../home/room/detail/RoomDetailViewModel.kt | 2 ++ .../features/settings/VectorPreferences.kt | 10 +++++++++ vector/src/main/res/values/strings.xml | 2 ++ .../res/xml/vector_settings_preferences.xml | 6 ++++++ 9 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt diff --git a/CHANGES.md b/CHANGES.md index 991078e704..574d3fe4be 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Features ✨: Improvements 🙌: - Better connectivity lost indicator when airplane mode is on + - Add a setting to hide redacted events (#951) Bugfix 🐛: - Fix issues with FontScale switch (#69, #645) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineSettings.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineSettings.kt index 992cad41ca..154074b722 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineSettings.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/timeline/TimelineSettings.kt @@ -28,6 +28,10 @@ data class TimelineSettings( * A flag to filter edit events */ val filterEdits: Boolean = false, + /** + * A flag to filter redacted events + */ + val filterRedacted: Boolean = false, /** * A flag to filter by types. It should be used with [allowedTypes] field */ diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt new file mode 100644 index 0000000000..110a1e785c --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.database.query + +internal object UnsignedContent { + internal const val REDACTED_TYPE = """{*"redacted_because":*}""" +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt index f2bee734ce..894d7dc8e6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt @@ -36,6 +36,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields import im.vector.matrix.android.internal.database.query.FilterContent +import im.vector.matrix.android.internal.database.query.UnsignedContent import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.whereInRoom @@ -727,6 +728,9 @@ internal class DefaultTimeline( not().like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.EDIT_TYPE) not().like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.RESPONSE_TYPE) } + if (settings.filterRedacted) { + not().like(TimelineEventEntityFields.ROOT.UNSIGNED_DATA, UnsignedContent.REDACTED_TYPE) + } return this } @@ -737,13 +741,19 @@ internal class DefaultTimeline( } else { true } + if (!filterType) return@filter false + val filterEdits = if (settings.filterEdits && it.root.type == EventType.MESSAGE) { val messageContent = it.root.content.toModel() messageContent?.relatesTo?.type != RelationType.REPLACE } else { true } - filterType && filterEdits + if (!filterEdits) return@filter false + + val filterRedacted = settings.filterRedacted && it.root.isRedacted() + + filterRedacted } } diff --git a/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt b/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt index ac379a8f98..fa4b09ed4c 100644 --- a/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt +++ b/vector/src/main/java/im/vector/riotx/core/resources/UserPreferencesProvider.kt @@ -29,6 +29,10 @@ class UserPreferencesProvider @Inject constructor(private val vectorPreferences: return vectorPreferences.showReadReceipts() } + fun shouldShowRedactedMessages(): Boolean { + return vectorPreferences.showRedactedMessages() + } + fun shouldShowLongClickOnRoomHelp(): Boolean { return vectorPreferences.shouldShowLongClickOnRoomHelp() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index d0dcac6ecc..4a767a178e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -99,11 +99,13 @@ class RoomDetailViewModel @AssistedInject constructor( private val timelineSettings = if (userPreferencesProvider.shouldShowHiddenEvents()) { TimelineSettings(30, filterEdits = false, + filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(), filterTypes = false, buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts()) } else { TimelineSettings(30, filterEdits = true, + filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(), filterTypes = true, allowedTypes = TimelineDisplayableEvents.DISPLAYABLE_TYPES, buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts()) diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt index c995c4d986..1455e2f8d8 100755 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorPreferences.kt @@ -88,6 +88,7 @@ class VectorPreferences @Inject constructor(private val context: Context) { private const val SETTINGS_ALWAYS_SHOW_TIMESTAMPS_KEY = "SETTINGS_ALWAYS_SHOW_TIMESTAMPS_KEY" private const val SETTINGS_12_24_TIMESTAMPS_KEY = "SETTINGS_12_24_TIMESTAMPS_KEY" private const val SETTINGS_SHOW_READ_RECEIPTS_KEY = "SETTINGS_SHOW_READ_RECEIPTS_KEY" + private const val SETTINGS_SHOW_REDACTED_KEY = "SETTINGS_SHOW_REDACTED_KEY" private const val SETTINGS_SHOW_JOIN_LEAVE_MESSAGES_KEY = "SETTINGS_SHOW_JOIN_LEAVE_MESSAGES_KEY" private const val SETTINGS_SHOW_AVATAR_DISPLAY_NAME_CHANGES_MESSAGES_KEY = "SETTINGS_SHOW_AVATAR_DISPLAY_NAME_CHANGES_MESSAGES_KEY" private const val SETTINGS_VIBRATE_ON_MENTION_KEY = "SETTINGS_VIBRATE_ON_MENTION_KEY" @@ -625,6 +626,15 @@ class VectorPreferences @Inject constructor(private val context: Context) { return defaultPrefs.getBoolean(SETTINGS_SHOW_READ_RECEIPTS_KEY, true) } + /** + * Tells if the redacted message should be shown + * + * @return true if the redacted should be shown + */ + fun showRedactedMessages(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_SHOW_REDACTED_KEY, true) + } + /** * Tells if the help on room list should be shown * diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index f9c45e2236..4dab1d3da0 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1564,6 +1564,8 @@ Why choose Riot.im? Reactions Message deleted + Show removed messages + Show a placeholder for removed messages Event deleted by user Event moderated by room admin Last edited by %1$s on %2$s diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index b1bd6ea5e6..d290b62825 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -70,6 +70,12 @@ android:summary="@string/settings_show_read_receipts_summary" android:title="@string/settings_show_read_receipts" /> + + Date: Mon, 18 May 2020 16:06:19 +0200 Subject: [PATCH 127/199] Ganfra's review: Handle filterRedacted in TimelineHiddenReadReceipts --- .../room/timeline/TimelineHiddenReadReceipts.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt index 056f942211..ce0f5c1b14 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt @@ -25,6 +25,7 @@ import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntit import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields import im.vector.matrix.android.internal.database.query.FilterContent +import im.vector.matrix.android.internal.database.query.UnsignedContent import im.vector.matrix.android.internal.database.query.whereInRoom import io.realm.OrderedRealmCollectionChangeListener import io.realm.Realm @@ -149,16 +150,21 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu */ private fun RealmQuery.filterReceiptsWithSettings(): RealmQuery { beginGroup() + var needOr = false if (settings.filterTypes) { not().`in`("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.TYPE}", settings.allowedTypes.toTypedArray()) - } - if (settings.filterTypes && settings.filterEdits) { - or() + needOr = true } if (settings.filterEdits) { + if (needOr) or() like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", FilterContent.EDIT_TYPE) or() like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", FilterContent.RESPONSE_TYPE) + needOr = true + } + if (settings.filterRedacted) { + if (needOr) or() + like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.UNSIGNED_DATA}", UnsignedContent.REDACTED_TYPE) } endGroup() return this From d45653dbb3731be69ded43e09fa14fcb984e2f20 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 18 May 2020 16:15:05 +0200 Subject: [PATCH 128/199] Ganfra's review: Improve the filters declaration --- .../query/TimelineEventEntityQueries.kt | 4 ++-- ...ilterContent.kt => TimelineEventFilter.kt} | 20 +++++++++++++++--- .../database/query/UnsignedContent.kt | 21 ------------------- .../session/room/timeline/DefaultTimeline.kt | 9 ++++---- .../timeline/TimelineHiddenReadReceipts.kt | 9 ++++---- 5 files changed, 27 insertions(+), 36 deletions(-) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/{FilterContent.kt => TimelineEventFilter.kt} (54%) delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt index 5168d0728e..f798dbcf41 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt @@ -62,8 +62,8 @@ internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm, val liveEvents = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)?.timelineEvents?.where()?.filterTypes(filterTypes) if (filterContentRelation) { liveEvents - ?.not()?.like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.EDIT_TYPE) - ?.not()?.like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.RESPONSE_TYPE) + ?.not()?.like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.EDIT) + ?.not()?.like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.RESPONSE) } val query = if (includesSending && sendingTimelineEvents.findAll().isNotEmpty()) { sendingTimelineEvents diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt similarity index 54% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterContent.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt index 6e89a28b7d..ea8122bc6d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/FilterContent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventFilter.kt @@ -16,8 +16,22 @@ package im.vector.matrix.android.internal.database.query -internal object FilterContent { +/** + * Query strings used to filter the timeline events regarding the Json raw string of the Event + */ +internal object TimelineEventFilter { + /** + * To apply to Event.content + */ + internal object Content { + internal const val EDIT = """{*"m.relates_to"*"rel_type":*"m.replace"*}""" + internal const val RESPONSE = """{*"m.relates_to"*"rel_type":*"m.response"*}""" + } - internal const val EDIT_TYPE = """{*"m.relates_to"*"rel_type":*"m.replace"*}""" - internal const val RESPONSE_TYPE = """{*"m.relates_to"*"rel_type":*"m.response"*}""" + /** + * To apply to Event.unsigned + */ + internal object Unsigned { + internal const val REDACTED = """{*"redacted_because":*}""" + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt deleted file mode 100644 index 110a1e785c..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/UnsignedContent.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2020 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.matrix.android.internal.database.query - -internal object UnsignedContent { - internal const val REDACTED_TYPE = """{*"redacted_because":*}""" -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt index 894d7dc8e6..bf6b81b57c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt @@ -35,8 +35,7 @@ import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryE import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields -import im.vector.matrix.android.internal.database.query.FilterContent -import im.vector.matrix.android.internal.database.query.UnsignedContent +import im.vector.matrix.android.internal.database.query.TimelineEventFilter import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.whereInRoom @@ -725,11 +724,11 @@ internal class DefaultTimeline( `in`(TimelineEventEntityFields.ROOT.TYPE, settings.allowedTypes.toTypedArray()) } if (settings.filterEdits) { - not().like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.EDIT_TYPE) - not().like(TimelineEventEntityFields.ROOT.CONTENT, FilterContent.RESPONSE_TYPE) + not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.EDIT) + not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.RESPONSE) } if (settings.filterRedacted) { - not().like(TimelineEventEntityFields.ROOT.UNSIGNED_DATA, UnsignedContent.REDACTED_TYPE) + not().like(TimelineEventEntityFields.ROOT.UNSIGNED_DATA, TimelineEventFilter.Unsigned.REDACTED) } return this } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt index ce0f5c1b14..72e99701cd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/TimelineHiddenReadReceipts.kt @@ -24,8 +24,7 @@ import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntit import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntityFields import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields -import im.vector.matrix.android.internal.database.query.FilterContent -import im.vector.matrix.android.internal.database.query.UnsignedContent +import im.vector.matrix.android.internal.database.query.TimelineEventFilter import im.vector.matrix.android.internal.database.query.whereInRoom import io.realm.OrderedRealmCollectionChangeListener import io.realm.Realm @@ -157,14 +156,14 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu } if (settings.filterEdits) { if (needOr) or() - like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", FilterContent.EDIT_TYPE) + like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.EDIT) or() - like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", FilterContent.RESPONSE_TYPE) + like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.RESPONSE) needOr = true } if (settings.filterRedacted) { if (needOr) or() - like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.UNSIGNED_DATA}", UnsignedContent.REDACTED_TYPE) + like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.UNSIGNED_DATA}", TimelineEventFilter.Unsigned.REDACTED) } endGroup() return this From 25bbd7c526e7d44cb0077ef2653ab80eb3d7e989 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 02:20:37 +0200 Subject: [PATCH 129/199] Identity - Create DB --- .../android/internal/di/DbQualifiers.kt | 4 ++ .../android/internal/session/SessionModule.kt | 20 +++++++ .../identity/db/IdentityRealmModule.kt | 28 ++++++++++ .../identity/db/IdentityServerEntity.kt | 30 ++++++++++ .../identity/db/IdentityServerQuery.kt | 56 +++++++++++++++++++ .../identity/db/IdentityServiceStore.kt | 30 ++++++++++ .../identity/db/RealmIdentityServerStore.kt | 53 ++++++++++++++++++ 7 files changed, 221 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityRealmModule.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerEntity.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/DbQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/DbQualifiers.kt index 3fdeb7eacc..fa007fdab6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/DbQualifiers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/DbQualifiers.kt @@ -29,3 +29,7 @@ annotation class SessionDatabase @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class CryptoDatabase + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class IdentityDatabase diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 8bdfff062f..7fdaf5fe02 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -39,9 +39,11 @@ import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageSer import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver import im.vector.matrix.android.internal.database.LiveEntityObserver +import im.vector.matrix.android.internal.database.RealmKeysUtils import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory import im.vector.matrix.android.internal.di.Authenticated import im.vector.matrix.android.internal.di.DeviceId +import im.vector.matrix.android.internal.di.IdentityDatabase import im.vector.matrix.android.internal.di.SessionCacheDirectory import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionFilesDirectory @@ -60,6 +62,7 @@ import im.vector.matrix.android.internal.network.RetrofitFactory import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.homeserver.DefaultHomeServerCapabilitiesService +import im.vector.matrix.android.internal.session.identity.db.IdentityRealmModule import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater import im.vector.matrix.android.internal.session.room.create.RoomCreateEventLiveObserver import im.vector.matrix.android.internal.session.room.prune.EventsPruner @@ -170,6 +173,23 @@ internal abstract class SessionModule { .build() } + @JvmStatic + @Provides + @IdentityDatabase + @SessionScope + fun providesIdentityRealmConfiguration(realmKeysUtils: RealmKeysUtils, + @SessionFilesDirectory directory: File, + @UserMd5 userMd5: String): RealmConfiguration { + return RealmConfiguration.Builder() + .directory(directory) + .name("matrix-sdk-identity.realm") + .apply { + realmKeysUtils.configureEncryption(this, getKeyAlias(userMd5)) + } + .modules(IdentityRealmModule()) + .build() + } + @JvmStatic @Provides @SessionScope diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityRealmModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityRealmModule.kt new file mode 100644 index 0000000000..d97c6a5715 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityRealmModule.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.db + +import io.realm.annotations.RealmModule + +/** + * Realm module for identity server classes + */ +@RealmModule(library = true, + classes = [ + IdentityServerEntity::class + ]) +internal class IdentityRealmModule diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerEntity.kt new file mode 100644 index 0000000000..5545f5bccf --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerEntity.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.db + +import io.realm.RealmList +import io.realm.RealmObject + +internal open class IdentityServerEntity( + var identityServerUrl: String? = null, + var token: String? = null, + var hashLookupPepper: String? = null, + var hashLookupAlgorithm: RealmList = RealmList() +) : RealmObject() { + + companion object +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt new file mode 100644 index 0000000000..6bef6109c3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.db + +import io.realm.Realm +import io.realm.RealmList +import io.realm.kotlin.createObject +import io.realm.kotlin.where + +/** + * Only one object can be stored at a time + */ +internal fun IdentityServerEntity.Companion.getOrCreate(realm: Realm): IdentityServerEntity { + return realm.where().findFirst() ?: realm.createObject() +} + +internal fun IdentityServerEntity.Companion.setUrl(realm: Realm, + url: String?) { + realm.where().findAll().deleteAllFromRealm() + + if (url != null) { + getOrCreate(realm).apply { + identityServerUrl = url + } + } +} + +internal fun IdentityServerEntity.Companion.setToken(realm: Realm, + newToken: String?) { + getOrCreate(realm).apply { + token = newToken + } +} + +internal fun IdentityServerEntity.Companion.setHashDetails(realm: Realm, + pepper: String, + algorithms: List) { + getOrCreate(realm).apply { + hashLookupPepper = pepper + hashLookupAlgorithm = RealmList().apply { addAll(algorithms) } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt new file mode 100644 index 0000000000..6933f0284f --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.db + +import im.vector.matrix.android.internal.session.identity.model.IdentityHashDetailResponse + +internal interface IdentityServiceStore { + + fun get(): IdentityServerEntity + + fun setUrl(url: String?) + + fun setToken(token: String?) + + fun setHashDetails(hashDetailResponse: IdentityHashDetailResponse) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt new file mode 100644 index 0000000000..96194b3dcd --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.db + +import im.vector.matrix.android.internal.di.IdentityDatabase +import im.vector.matrix.android.internal.session.identity.model.IdentityHashDetailResponse +import io.realm.Realm +import io.realm.RealmConfiguration +import javax.inject.Inject + +internal class RealmIdentityServerStore @Inject constructor( + @IdentityDatabase + private val realmConfiguration: RealmConfiguration +) : IdentityServiceStore { + + override fun get(): IdentityServerEntity { + return Realm.getInstance(realmConfiguration).use { + IdentityServerEntity.getOrCreate(it) + } + } + + override fun setUrl(url: String?) { + Realm.getInstance(realmConfiguration).use { + IdentityServerEntity.setUrl(it, url) + } + } + + override fun setToken(token: String?) { + Realm.getInstance(realmConfiguration).use { + IdentityServerEntity.setToken(it, token) + } + } + + override fun setHashDetails(hashDetailResponse: IdentityHashDetailResponse) { + Realm.getInstance(realmConfiguration).use { + IdentityServerEntity.setHashDetails(it, hashDetailResponse.pepper, hashDetailResponse.algorithms) + } + } +} From 9b7c2599a78f17391c2c6f8f83b40d7333cb1122 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 02:21:09 +0200 Subject: [PATCH 130/199] Add withOlmUtility facility --- .../matrix/android/internal/crypto/tools/Tools.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt index c3d2c30079..5e406fdc4f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tools/Tools.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.crypto.tools import org.matrix.olm.OlmPkDecryption import org.matrix.olm.OlmPkEncryption import org.matrix.olm.OlmPkSigning +import org.matrix.olm.OlmUtility fun withOlmEncryption(block: (OlmPkEncryption) -> T): T { val olmPkEncryption = OlmPkEncryption() @@ -46,3 +47,12 @@ fun withOlmSigning(block: (OlmPkSigning) -> T): T { olmPkSigning.releaseSigning() } } + +fun withOlmUtility(block: (OlmUtility) -> T): T { + val olmUtility = OlmUtility() + try { + return block(olmUtility) + } finally { + olmUtility.releaseUtility() + } +} From 6c9c3e5cb373b3546b0d8e19913f4a287753d042 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 11:38:36 +0200 Subject: [PATCH 131/199] To merge with previous previous commit --- .../model/IdentityHashDetailResponse.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityHashDetailResponse.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityHashDetailResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityHashDetailResponse.kt new file mode 100644 index 0000000000..17cb25fdaf --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityHashDetailResponse.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Ref: https://github.com/matrix-org/matrix-doc/blob/hs/hash-identity/proposals/2134-identity-hash-lookup.md + */ +@JsonClass(generateAdapter = true) +internal data class IdentityHashDetailResponse( + @Json(name = "lookup_pepper") + val pepper: String, + + /** + * "sha256" must be supported by client. "none" can be another possible value. + */ + @Json(name = "algorithms") + val algorithms: List +) From f489265ce725dbbf1387d28cf4fd58c558ff89d7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 12:00:16 +0200 Subject: [PATCH 132/199] Create AccessTokenProvider --- .idea/dictionaries/bmarty.xml | 1 + .../internal/di/AccessTokenQualifiers.kt | 28 +++++++++++++++++++ .../network/AccessTokenInterceptor.kt | 13 ++------- .../network/token/AccessTokenProvider.kt | 21 ++++++++++++++ .../token/HomeserverAccessTokenProvider.kt | 26 +++++++++++++++++ .../android/internal/session/SessionModule.kt | 20 +++++++++++-- 6 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/AccessTokenProvider.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml index 1f93d1feee..26606fedd0 100644 --- a/.idea/dictionaries/bmarty.xml +++ b/.idea/dictionaries/bmarty.xml @@ -12,6 +12,7 @@ fdroid gplay hmac + homeserver ktlint linkified linkify diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt new file mode 100644 index 0000000000..328cf54c23 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.di + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class HomeserverAccessToken + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class IdentityServerAccessToken + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt index c802d4b63a..a15f660790 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt @@ -16,20 +16,16 @@ package im.vector.matrix.android.internal.network -import im.vector.matrix.android.internal.auth.SessionParamsStore -import im.vector.matrix.android.internal.di.SessionId +import im.vector.matrix.android.internal.network.token.AccessTokenProvider import okhttp3.Interceptor import okhttp3.Response -import javax.inject.Inject -internal class AccessTokenInterceptor @Inject constructor( - @SessionId private val sessionId: String, - private val sessionParamsStore: SessionParamsStore) : Interceptor { +internal class AccessTokenInterceptor(private val accessTokenProvider: AccessTokenProvider) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() - accessToken?.let { + accessTokenProvider.getToken()?.let { val newRequestBuilder = request.newBuilder() // Add the access token to all requests if it is set newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer $it") @@ -38,7 +34,4 @@ internal class AccessTokenInterceptor @Inject constructor( return chain.proceed(request) } - - private val accessToken - get() = sessionParamsStore.get(sessionId)?.credentials?.accessToken } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/AccessTokenProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/AccessTokenProvider.kt new file mode 100644 index 0000000000..4d6da8a4bf --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/AccessTokenProvider.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.network.token + +interface AccessTokenProvider { + fun getToken(): String? +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt new file mode 100644 index 0000000000..3575eef900 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.network.token + +import im.vector.matrix.android.internal.auth.SessionParamsStore + +internal class HomeserverAccessTokenProvider( + private val sessionId: String, + private val sessionParamsStore: SessionParamsStore +) : AccessTokenProvider { + override fun getToken() = sessionParamsStore.get(sessionId)?.credentials?.accessToken +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 7fdaf5fe02..46849cf3e1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -36,6 +36,7 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService import im.vector.matrix.android.api.session.securestorage.SecureStorageService import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService +import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver import im.vector.matrix.android.internal.database.LiveEntityObserver @@ -43,6 +44,7 @@ import im.vector.matrix.android.internal.database.RealmKeysUtils import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory import im.vector.matrix.android.internal.di.Authenticated import im.vector.matrix.android.internal.di.DeviceId +import im.vector.matrix.android.internal.di.HomeserverAccessToken import im.vector.matrix.android.internal.di.IdentityDatabase import im.vector.matrix.android.internal.di.SessionCacheDirectory import im.vector.matrix.android.internal.di.SessionDatabase @@ -60,6 +62,8 @@ import im.vector.matrix.android.internal.network.NetworkConnectivityChecker import im.vector.matrix.android.internal.network.PreferredNetworkCallbackStrategy import im.vector.matrix.android.internal.network.RetrofitFactory import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor +import im.vector.matrix.android.internal.network.token.AccessTokenProvider +import im.vector.matrix.android.internal.network.token.HomeserverAccessTokenProvider import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.homeserver.DefaultHomeServerCapabilitiesService import im.vector.matrix.android.internal.session.identity.db.IdentityRealmModule @@ -195,14 +199,14 @@ internal abstract class SessionModule { @SessionScope @Authenticated fun providesOkHttpClient(@Unauthenticated okHttpClient: OkHttpClient, - accessTokenInterceptor: AccessTokenInterceptor): OkHttpClient { + @Authenticated accessTokenProvider: AccessTokenProvider): OkHttpClient { return okHttpClient.newBuilder() .apply { // Remove the previous CurlLoggingInterceptor, to add it after the accessTokenInterceptor val existingCurlInterceptors = interceptors().filterIsInstance() interceptors().removeAll(existingCurlInterceptors) - addInterceptor(accessTokenInterceptor) + addInterceptor(AccessTokenInterceptor(accessTokenProvider)) // Re add eventually the curl logging interceptors existingCurlInterceptors.forEach { @@ -212,6 +216,14 @@ internal abstract class SessionModule { .build() } + @JvmStatic + @Provides + @Authenticated + fun providesAccessTokenProvider(@SessionId sessionId: String, + sessionParamsStore: SessionParamsStore): AccessTokenProvider { + return HomeserverAccessTokenProvider(sessionId, sessionParamsStore) + } + @JvmStatic @Provides @SessionScope @@ -253,6 +265,10 @@ internal abstract class SessionModule { } } + @Binds + @HomeserverAccessToken + abstract fun bindAccessTokenProvider(provider: HomeserverAccessTokenProvider): AccessTokenProvider + @Binds abstract fun bindSession(session: DefaultSession): Session From ab6e7a3b8a72bbf931f36fa33abf298dea0a9a1b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 14:22:59 +0200 Subject: [PATCH 133/199] Identity - WIP (compilation ok) --- .../matrix/android/api/failure/MatrixError.kt | 2 + .../matrix/android/api/session/Session.kt | 6 + .../session/identity/FoundThreePid.kt} | 16 +- .../api/session/identity/IdentityService.kt | 46 ++++ .../session/identity/IdentityServiceError.kt | 23 ++ .../identity/IdentityServiceListener.kt | 21 ++ .../android/api/session/identity/ThreePid.kt | 22 ++ .../attachments/MXEncryptedAttachments.kt | 2 +- .../android/internal/di/AuthQualifiers.kt | 5 + .../token/HomeserverAccessTokenProvider.kt | 6 +- .../internal/session/DefaultSession.kt | 8 +- .../internal/session/SessionComponent.kt | 2 + .../android/internal/session/SessionModule.kt | 12 +- .../session/identity/BulkLookupTask.kt | 98 ++++++++ .../identity/DefaultIdentityService.kt | 220 ++++++++++++++++++ .../internal/session/identity/IdentityAPI.kt | 73 ++++++ .../identity/IdentityAccessTokenProvider.kt | 27 +++ .../session/identity/IdentityApiProvider.kt | 26 +++ .../session/identity/IdentityAuthAPI.kt | 50 ++++ .../session/identity/IdentityModule.kt | 73 ++++++ .../session/identity/IdentityRegisterTask.kt | 39 ++++ .../identity/model/IdentityAccountResponse.kt | 27 +++ .../identity/model/IdentityLookUpV2Params.kt | 37 +++ .../model/IdentityLookUpV2Response.kt | 29 +++ .../model/IdentityRegisterResponse.kt | 29 +++ .../model/IdentityRequestOwnershipParams.kt | 31 +++ .../todelete/AccountDataDataSource.kt | 66 ++++++ .../identity/todelete/AccountDataMapper.kt | 36 +++ .../session/identity/todelete/LiveData.kt | 30 +++ .../sync/model/accountdata/UserAccountData.kt | 1 + .../accountdata/UserAccountDataIdentity.kt | 31 +++ .../accountdata/UpdateUserAccountDataTask.kt | 10 + 32 files changed, 1078 insertions(+), 26 deletions(-) rename matrix-sdk-android/src/main/java/im/vector/matrix/android/{internal/di/AccessTokenQualifiers.kt => api/session/identity/FoundThreePid.kt} (69%) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceListener.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAPI.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityApiProvider.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAuthAPI.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityModule.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityRegisterTask.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityAccountResponse.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Params.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Response.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRegisterResponse.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRequestOwnershipParams.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataDataSource.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataMapper.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/LiveData.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt index d7a6954fd5..2dcead7477 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt @@ -129,6 +129,8 @@ data class MatrixError( /** (Not documented yet) */ const val M_WRONG_ROOM_KEYS_VERSION = "M_WRONG_ROOM_KEYS_VERSION" + const val M_TERMS_NOT_SIGNED = "M_TERMS_NOT_SIGNED" + // Possible value for "limit_type" const val LIMIT_TYPE_MAU = "monthly_active_user" } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt index 1afeed922f..1143732b09 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt @@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.file.FileService import im.vector.matrix.android.api.session.group.GroupService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService +import im.vector.matrix.android.api.session.identity.IdentityService import im.vector.matrix.android.api.session.profile.ProfileService import im.vector.matrix.android.api.session.pushers.PushersService import im.vector.matrix.android.api.session.room.RoomDirectoryService @@ -145,6 +146,11 @@ interface Session : */ fun cryptoService(): CryptoService + /** + * Returns the identity service associated with the session + */ + fun identityService(): IdentityService + /** * Add a listener to the session. * @param listener the listener to add. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt similarity index 69% rename from matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt rename to matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt index 328cf54c23..5817699636 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AccessTokenQualifiers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt @@ -14,15 +14,9 @@ * limitations under the License. */ -package im.vector.matrix.android.internal.di - -import javax.inject.Qualifier - -@Qualifier -@Retention(AnnotationRetention.RUNTIME) -annotation class HomeserverAccessToken - -@Qualifier -@Retention(AnnotationRetention.RUNTIME) -annotation class IdentityServerAccessToken +package im.vector.matrix.android.api.session.identity +data class FoundThreePid( + val threePid: ThreePid, + val matrixId: String +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt new file mode 100644 index 0000000000..0a844d0921 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.identity + +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.util.Cancelable + +/** + * Provides access to the identity server configuration and services identity server can provide + */ +interface IdentityService { + + /** + * Return the default identity server of the homeserver (using Wellknown request) + */ + fun getDefaultIdentityServer(): String? + + fun getCurrentIdentityServer(): String? + + fun setNewIdentityServer(url: String?, callback: MatrixCallback): Cancelable + + fun disconnect() + + fun bindThreePid() + + fun unbindThreePid() + + fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable + + fun addListener(listener: IdentityServiceListener) + fun removeListener(listener: IdentityServiceListener) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt new file mode 100644 index 0000000000..7b05409f09 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceError.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.identity + +sealed class IdentityServiceError(cause: Throwable? = null) : Throwable(cause = cause) { + object NoIdentityServerConfigured : IdentityServiceError(null) + object TermsNotSignedException : IdentityServiceError(null) + object BulkLookupSha256NotSupported : IdentityServiceError(null) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceListener.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceListener.kt new file mode 100644 index 0000000000..13f622fe77 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityServiceListener.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.identity + +interface IdentityServiceListener { + fun onIdentityServerChange() +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt new file mode 100644 index 0000000000..7aabb2b9e0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.api.session.identity + +sealed class ThreePid(open val value: String) { + data class Email(val email: String) : ThreePid(email) + data class Msisdn(val msisdn: String) : ThreePid(msisdn) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt index e83895709e..19243f1a23 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -199,7 +199,7 @@ internal object MXEncryptedAttachments { .replace('_', '/') } - private fun base64ToBase64Url(base64: String): String { + internal fun base64ToBase64Url(base64: String): String { return base64.replace("\n".toRegex(), "") .replace("\\+".toRegex(), "-") .replace('/', '_') diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt index 8ee27b3375..47f255cd40 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt @@ -18,10 +18,15 @@ package im.vector.matrix.android.internal.di import javax.inject.Qualifier +// TODO Add internal ? @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class Authenticated +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class AuthenticatedIdentity + @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class Unauthenticated diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt index 3575eef900..b570cb362e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/token/HomeserverAccessTokenProvider.kt @@ -17,9 +17,11 @@ package im.vector.matrix.android.internal.network.token import im.vector.matrix.android.internal.auth.SessionParamsStore +import im.vector.matrix.android.internal.di.SessionId +import javax.inject.Inject -internal class HomeserverAccessTokenProvider( - private val sessionId: String, +internal class HomeserverAccessTokenProvider @Inject constructor( + @SessionId private val sessionId: String, private val sessionParamsStore: SessionParamsStore ) : AccessTokenProvider { override fun getToken() = sessionParamsStore.get(sessionId)?.credentials?.accessToken diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index b30c29a719..1dfade2388 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -50,6 +50,7 @@ import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater import im.vector.matrix.android.internal.database.LiveEntityObserver import im.vector.matrix.android.internal.di.SessionId import im.vector.matrix.android.internal.di.WorkManagerProvider +import im.vector.matrix.android.internal.session.identity.DefaultIdentityService import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecryptor import im.vector.matrix.android.internal.session.sync.SyncTokenStore import im.vector.matrix.android.internal.session.sync.job.SyncThread @@ -97,7 +98,8 @@ internal class DefaultSession @Inject constructor( private val _sharedSecretStorageService: Lazy, private val accountService: Lazy, private val timelineEventDecryptor: TimelineEventDecryptor, - private val shieldTrustUpdater: ShieldTrustUpdater) + private val shieldTrustUpdater: ShieldTrustUpdater, + private val defaultIdentityService: DefaultIdentityService) : Session, RoomService by roomService.get(), RoomDirectoryService by roomDirectoryService.get(), @@ -133,6 +135,7 @@ internal class DefaultSession @Inject constructor( eventBus.register(this) timelineEventDecryptor.start() shieldTrustUpdater.start() + defaultIdentityService.start() } override fun requireBackgroundSync() { @@ -175,6 +178,7 @@ internal class DefaultSession @Inject constructor( isOpen = false eventBus.unregister(this) shieldTrustUpdater.stop() + defaultIdentityService.stop() } override fun getSyncStateLive(): LiveData { @@ -218,6 +222,8 @@ internal class DefaultSession @Inject constructor( override fun cryptoService(): CryptoService = cryptoService.get() + override fun identityService() = defaultIdentityService + override fun addListener(listener: Session.Listener) { sessionListeners.addListener(listener) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt index 0ebfc1c4c5..a6e3d9493c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionComponent.kt @@ -36,6 +36,7 @@ import im.vector.matrix.android.internal.session.filter.FilterModule import im.vector.matrix.android.internal.session.group.GetGroupDataWorker import im.vector.matrix.android.internal.session.group.GroupModule import im.vector.matrix.android.internal.session.homeserver.HomeServerCapabilitiesModule +import im.vector.matrix.android.internal.session.identity.IdentityModule import im.vector.matrix.android.internal.session.openid.OpenIdModule import im.vector.matrix.android.internal.session.profile.ProfileModule import im.vector.matrix.android.internal.session.pushers.AddHttpPusherWorker @@ -72,6 +73,7 @@ import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers CryptoModule::class, PushersModule::class, OpenIdModule::class, + IdentityModule::class, AccountDataModule::class, ProfileModule::class, SessionAssistedInjectModule::class, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 46849cf3e1..3f9c5a2364 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -36,7 +36,6 @@ import im.vector.matrix.android.api.session.accountdata.AccountDataService import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService import im.vector.matrix.android.api.session.securestorage.SecureStorageService import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService -import im.vector.matrix.android.internal.auth.SessionParamsStore import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver import im.vector.matrix.android.internal.database.LiveEntityObserver @@ -44,7 +43,6 @@ import im.vector.matrix.android.internal.database.RealmKeysUtils import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory import im.vector.matrix.android.internal.di.Authenticated import im.vector.matrix.android.internal.di.DeviceId -import im.vector.matrix.android.internal.di.HomeserverAccessToken import im.vector.matrix.android.internal.di.IdentityDatabase import im.vector.matrix.android.internal.di.SessionCacheDirectory import im.vector.matrix.android.internal.di.SessionDatabase @@ -216,14 +214,6 @@ internal abstract class SessionModule { .build() } - @JvmStatic - @Provides - @Authenticated - fun providesAccessTokenProvider(@SessionId sessionId: String, - sessionParamsStore: SessionParamsStore): AccessTokenProvider { - return HomeserverAccessTokenProvider(sessionId, sessionParamsStore) - } - @JvmStatic @Provides @SessionScope @@ -266,7 +256,7 @@ internal abstract class SessionModule { } @Binds - @HomeserverAccessToken + @Authenticated abstract fun bindAccessTokenProvider(provider: HomeserverAccessTokenProvider): AccessTokenProvider @Binds diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt new file mode 100644 index 0000000000..9d701ad7c5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.api.session.identity.FoundThreePid +import im.vector.matrix.android.api.session.identity.IdentityServiceError +import im.vector.matrix.android.api.session.identity.ThreePid +import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments.base64ToBase64Url +import im.vector.matrix.android.internal.crypto.tools.withOlmUtility +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.identity.db.IdentityServiceStore +import im.vector.matrix.android.internal.session.identity.model.IdentityHashDetailResponse +import im.vector.matrix.android.internal.session.identity.model.IdentityLookUpV2Params +import im.vector.matrix.android.internal.session.identity.model.IdentityLookUpV2Response +import im.vector.matrix.android.internal.task.Task +import java.util.Locale +import javax.inject.Inject + +internal interface BulkLookupTask : Task> { + data class Params( + val threePids: List + ) +} + +internal class DefaultBulkLookupTask @Inject constructor( + private val identityApiProvider: IdentityApiProvider, + private val identityServiceStore: IdentityServiceStore +) : BulkLookupTask { + + override suspend fun execute(params: BulkLookupTask.Params): List { + val identityAPI = identityApiProvider.identityApi ?: throw IdentityServiceError.NoIdentityServerConfigured + val entity = identityServiceStore.get() + val pepper = entity.hashLookupPepper + val hashDetailResponse = if (pepper == null) { + // We need to fetch the hash details first + executeRequest(null) { + apiCall = identityAPI.hashDetails() + } + .also { identityServiceStore.setHashDetails(it) } + } else { + IdentityHashDetailResponse(pepper, entity.hashLookupAlgorithm.toList()) + } + + if (hashDetailResponse.algorithms.contains("sha256").not()) { + // TODO We should ask the user if he is ok to send their 3Pid in clear, but for the moment do not do it + throw IdentityServiceError.BulkLookupSha256NotSupported + } + + val hashedAddresses = withOlmUtility { olmUtility -> + params.threePids.map { threePid -> + base64ToBase64Url( + olmUtility.sha256(threePid.value.toLowerCase(Locale.ROOT) + + " " + threePid.toMedium() + " " + hashDetailResponse.pepper) + ) + } + } + + val identityLookUpV2Response = executeRequest(null) { + apiCall = identityAPI.bulkLookupV2(IdentityLookUpV2Params( + hashedAddresses, + "sha256", + hashDetailResponse.pepper + )) + } + + // TODO Catch invalid hash pepper and retry + + // Convert back to List + return handleSuccess(params.threePids, hashedAddresses, identityLookUpV2Response) + } + + private fun handleSuccess(threePids: List, hashedAddresses: List, identityLookUpV2Response: IdentityLookUpV2Response): List { + return identityLookUpV2Response.mappings.keys.map { hashedAddress -> + FoundThreePid(threePids[hashedAddresses.indexOf(hashedAddress)], identityLookUpV2Response.mappings[hashedAddress] ?: error("")) + } + } + + private fun ThreePid.toMedium(): String { + return when (this) { + is ThreePid.Email -> "email" + is ThreePid.Msisdn -> "msisdn" + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt new file mode 100644 index 0000000000..f02e5446d8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LifecycleRegistry +import dagger.Lazy +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.failure.MatrixError +import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.identity.FoundThreePid +import im.vector.matrix.android.api.session.identity.IdentityService +import im.vector.matrix.android.api.session.identity.IdentityServiceError +import im.vector.matrix.android.api.session.identity.IdentityServiceListener +import im.vector.matrix.android.api.session.identity.ThreePid +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.di.AuthenticatedIdentity +import im.vector.matrix.android.internal.di.Unauthenticated +import im.vector.matrix.android.internal.network.RetrofitFactory +import im.vector.matrix.android.internal.session.SessionScope +import im.vector.matrix.android.internal.session.identity.db.IdentityServiceStore +import im.vector.matrix.android.internal.session.identity.todelete.AccountDataDataSource +import im.vector.matrix.android.internal.session.identity.todelete.observeNotNull +import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask +import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityContent +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataIdentity +import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask +import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.task.launchToCallback +import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers +import kotlinx.coroutines.GlobalScope +import okhttp3.OkHttpClient +import timber.log.Timber +import javax.inject.Inject +import javax.net.ssl.HttpsURLConnection + +@SessionScope +internal class DefaultIdentityService @Inject constructor( + private val identityServiceStore: IdentityServiceStore, + private val openIdTokenTask: GetOpenIdTokenTask, + private val bulkLookupTask: BulkLookupTask, + private val identityRegisterTask: IdentityRegisterTask, + private val taskExecutor: TaskExecutor, + @Unauthenticated + private val unauthenticatedOkHttpClient: Lazy, + @AuthenticatedIdentity + private val okHttpClient: Lazy, + private val retrofitFactory: RetrofitFactory, + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val updateUserAccountDataTask: UpdateUserAccountDataTask, + private val identityApiProvider: IdentityApiProvider, + private val accountDataDataSource: AccountDataDataSource +) : IdentityService { + + private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry } + private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner) + + private val listeners = mutableSetOf() + + fun start() { + lifecycleRegistry.currentState = Lifecycle.State.STARTED + // Observe the account data change + accountDataDataSource + .getLiveAccountDataEvent(UserAccountData.TYPE_IDENTITY) + .observeNotNull(lifecycleOwner) { + val identityServerContent = it.getOrNull()?.content?.toModel() + if (identityServerContent != null) { + notifyIdentityServerUrlChange(identityServerContent.content?.baseUrl) + } + // TODO Handle the case where the account data is deleted? + } + } + + private fun notifyIdentityServerUrlChange(baseUrl: String?) { + // This is maybe not a real change (local echo of account data we are just setting + if (identityServiceStore.get().identityServerUrl == baseUrl) { + Timber.d("Local echo of identity server url change") + } else { + // Url has changed, we have to reset our store, update internal configuration and notify listeners + identityServiceStore.setUrl(baseUrl) + updateIdentityAPI(baseUrl) + listeners.toList().forEach { it.onIdentityServerChange() } + } + } + + fun stop() { + lifecycleRegistry.currentState = Lifecycle.State.DESTROYED + } + + override fun getDefaultIdentityServer(): String? { + TODO("Not yet implemented") + } + + override fun getCurrentIdentityServer(): String? { + return identityServiceStore.get().identityServerUrl + } + + override fun disconnect() { + TODO("Not yet implemented") + } + + override fun setNewIdentityServer(url: String?, callback: MatrixCallback): Cancelable { + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { + val current = getCurrentIdentityServer() + when (url) { + current -> + // Nothing to do + Timber.d("Same URL, nothing to do") + null -> { + // TODO + // Disconnect previous one if any + identityServiceStore.setUrl(null) + updateAccountData(null) + } + else -> { + // TODO: check first that it is a valid identity server + updateAccountData(url) + } + } + } + } + + private suspend fun updateAccountData(url: String?) { + updateUserAccountDataTask.execute(UpdateUserAccountDataTask.IdentityParams( + identityContent = IdentityContent(baseUrl = url) + )) + } + + override fun bindThreePid() { + TODO("Not yet implemented") + } + + override fun unbindThreePid() { + TODO("Not yet implemented") + } + + override fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable { + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { + lookUpInternal(true, threePids) + } + } + + private suspend fun lookUpInternal(firstTime: Boolean, threePids: List): List { + ensureToken() + + return try { + bulkLookupTask.execute(BulkLookupTask.Params(threePids)) + } catch (throwable: Throwable) { + // Refresh token? + when { + throwable.isInvalidToken() && firstTime -> { + identityServiceStore.setToken(null) + lookUpInternal(false, threePids) + } + throwable.isTermsNotSigned() -> throw IdentityServiceError.TermsNotSignedException + else -> throw throwable + } + } + } + + private suspend fun ensureToken() { + val entity = identityServiceStore.get() + val url = entity.identityServerUrl ?: throw IdentityServiceError.NoIdentityServerConfigured + + if (entity.token == null) { + // Try to get a token + val openIdToken = openIdTokenTask.execute(Unit) + + val api = retrofitFactory.create(unauthenticatedOkHttpClient, url).create(IdentityAuthAPI::class.java) + val token = identityRegisterTask.execute(IdentityRegisterTask.Params(api, openIdToken)) + + identityServiceStore.setToken(token.token) + } + } + + override fun addListener(listener: IdentityServiceListener) { + listeners.add(listener) + } + + override fun removeListener(listener: IdentityServiceListener) { + listeners.remove(listener) + } + + private fun updateIdentityAPI(url: String?) { + if (url == null) { + identityApiProvider.identityApi = null + } else { + val retrofit = retrofitFactory.create(okHttpClient, url) + identityApiProvider.identityApi = retrofit.create(IdentityAPI::class.java) + } + } +} + +private fun Throwable.isInvalidToken(): Boolean { + return this is Failure.ServerError + && this.httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED /* 401 */ +} + +private fun Throwable.isTermsNotSigned(): Boolean { + return this is Failure.ServerError + && httpCode == HttpsURLConnection.HTTP_FORBIDDEN /* 403 */ + && error.code == MatrixError.M_TERMS_NOT_SIGNED +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAPI.kt new file mode 100644 index 0000000000..5f65db3554 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAPI.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.internal.auth.registration.SuccessResult +import im.vector.matrix.android.internal.network.NetworkConstants +import im.vector.matrix.android.internal.session.identity.model.IdentityAccountResponse +import im.vector.matrix.android.internal.session.identity.model.IdentityHashDetailResponse +import im.vector.matrix.android.internal.session.identity.model.IdentityLookUpV2Params +import im.vector.matrix.android.internal.session.identity.model.IdentityLookUpV2Response +import im.vector.matrix.android.internal.session.identity.model.IdentityRequestOwnershipParams +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Path + +/** + * Ref: https://matrix.org/docs/spec/identity_service/latest + * This contain the requests which need an identity server token + */ +internal interface IdentityAPI { + /** + * Gets information about what user owns the access token used in the request. + * Will return a 403 for when terms are not signed + */ + @GET(NetworkConstants.URI_IDENTITY_PATH_V2 + "account") + fun getAccount(): Call + + /** + * Logs out the access token, preventing it from being used to authenticate future requests to the server. + */ + @POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "logout") + fun logout(): Call + + /** + * Request the hash detail to request a bunch of 3PIDs + */ + @GET(NetworkConstants.URI_IDENTITY_PATH_V2 + "hash_details") + fun hashDetails(): Call + + /** + * Request a bunch of 3PIDs + * + * @param body the body request + */ + @POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "lookup") + fun bulkLookupV2(@Body body: IdentityLookUpV2Params): Call + + /** + * Request the ownership validation of an email address or a phone number previously set + * by [ProfileApi.requestEmailValidation] + * + * @param medium the medium of the 3pid + */ + @POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "validate/{medium}/submitToken") + fun requestOwnershipValidationV2(@Path("medium") medium: String?, + @Body body: IdentityRequestOwnershipParams): Call +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt new file mode 100644 index 0000000000..2fe2ca033b --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.internal.network.token.AccessTokenProvider +import im.vector.matrix.android.internal.session.identity.db.IdentityServiceStore +import javax.inject.Inject + +internal class IdentityAccessTokenProvider @Inject constructor( + private val identityServiceStore: IdentityServiceStore +) : AccessTokenProvider { + override fun getToken() = identityServiceStore.get().token +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityApiProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityApiProvider.kt new file mode 100644 index 0000000000..3262a56398 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityApiProvider.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.internal.session.SessionScope +import javax.inject.Inject + +@SessionScope +internal class IdentityApiProvider @Inject constructor() { + + var identityApi: IdentityAPI? = null +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAuthAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAuthAPI.kt new file mode 100644 index 0000000000..7b61f2522e --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAuthAPI.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.internal.network.NetworkConstants +import im.vector.matrix.android.internal.session.identity.model.IdentityRegisterResponse +import im.vector.matrix.android.internal.session.openid.RequestOpenIdTokenResponse +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST + +/** + * Ref: https://matrix.org/docs/spec/identity_service/latest + * This contain the requests which do not need an identity server token + */ +internal interface IdentityAuthAPI { + + /** + * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery + * Simple ping call to check if server alive + * + * Ref: https://matrix.org/docs/spec/identity_service/unstable#status-check + * + * @return 200 in case of success + */ + @GET(NetworkConstants.URI_API_PREFIX_IDENTITY) + fun ping(): Call + + /** + * Exchanges an OpenID token from the homeserver for an access token to access the identity server. + * The request body is the same as the values returned by /openid/request_token in the Client-Server API. + */ + @POST(NetworkConstants.URI_IDENTITY_PATH_V2 + "account/register") + fun register(@Body openIdToken: RequestOpenIdTokenResponse): Call +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityModule.kt new file mode 100644 index 0000000000..b320bac28d --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityModule.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import dagger.Binds +import dagger.Module +import dagger.Provides +import im.vector.matrix.android.internal.di.AuthenticatedIdentity +import im.vector.matrix.android.internal.di.Unauthenticated +import im.vector.matrix.android.internal.network.AccessTokenInterceptor +import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor +import im.vector.matrix.android.internal.network.token.AccessTokenProvider +import im.vector.matrix.android.internal.session.SessionScope +import im.vector.matrix.android.internal.session.identity.db.IdentityServiceStore +import im.vector.matrix.android.internal.session.identity.db.RealmIdentityServerStore +import okhttp3.OkHttpClient + +@Module +internal abstract class IdentityModule { + + @Module + companion object { + @JvmStatic + @Provides + @SessionScope + @AuthenticatedIdentity + fun providesOkHttpClient(@Unauthenticated okHttpClient: OkHttpClient, + @AuthenticatedIdentity accessTokenProvider: AccessTokenProvider): OkHttpClient { + // TODO Create an helper because there is code duplication + return okHttpClient.newBuilder() + .apply { + // Remove the previous CurlLoggingInterceptor, to add it after the accessTokenInterceptor + val existingCurlInterceptors = interceptors().filterIsInstance() + interceptors().removeAll(existingCurlInterceptors) + + addInterceptor(AccessTokenInterceptor(accessTokenProvider)) + + // Re add eventually the curl logging interceptors + existingCurlInterceptors.forEach { + addInterceptor(it) + } + } + .build() + } + } + + @Binds + @AuthenticatedIdentity + abstract fun bindAccessTokenProvider(provider: IdentityAccessTokenProvider): AccessTokenProvider + + @Binds + abstract fun bindIdentityServiceStore(store: RealmIdentityServerStore): IdentityServiceStore + + @Binds + abstract fun bindIdentityRegisterTask(task: DefaultIdentityRegisterTask): IdentityRegisterTask + + @Binds + abstract fun bindBulkLookupTask(task: DefaultBulkLookupTask): BulkLookupTask +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityRegisterTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityRegisterTask.kt new file mode 100644 index 0000000000..c72e364ef8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityRegisterTask.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity + +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.identity.model.IdentityRegisterResponse +import im.vector.matrix.android.internal.session.openid.RequestOpenIdTokenResponse +import im.vector.matrix.android.internal.task.Task +import javax.inject.Inject + +internal interface IdentityRegisterTask : Task { + data class Params( + val identityAuthAPI: IdentityAuthAPI, + val openIdTokenResponse: RequestOpenIdTokenResponse + ) +} + +internal class DefaultIdentityRegisterTask @Inject constructor() : IdentityRegisterTask { + + override suspend fun execute(params: IdentityRegisterTask.Params): IdentityRegisterResponse { + return executeRequest(null) { + apiCall = params.identityAuthAPI.register(params.openIdTokenResponse) + } + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityAccountResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityAccountResponse.kt new file mode 100644 index 0000000000..d24fc77274 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityAccountResponse.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class IdentityAccountResponse( + @Json(name = "user_id") + val userId: String +) + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Params.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Params.kt new file mode 100644 index 0000000000..acdad92758 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Params.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Ref: https://github.com/matrix-org/matrix-doc/blob/hs/hash-identity/proposals/2134-identity-hash-lookup.md + */ +@JsonClass(generateAdapter = true) +internal data class IdentityLookUpV2Params( + @Json(name = "addresses") + val hashedAddresses: List, + + @JvmField + @Json(name = "algorithm") + val algorithm: String, + + @JvmField + @Json(name = "pepper") + val pepper: String +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Response.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Response.kt new file mode 100644 index 0000000000..825e6c0017 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityLookUpV2Response.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +/** + * Ref: https://github.com/matrix-org/matrix-doc/blob/hs/hash-identity/proposals/2134-identity-hash-lookup.md + */ +@JsonClass(generateAdapter = true) +internal data class IdentityLookUpV2Response( + @Json(name = "mappings") + val mappings: Map +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRegisterResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRegisterResponse.kt new file mode 100644 index 0000000000..b99b0f0d53 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRegisterResponse.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class IdentityRegisterResponse( + /** + * A token which can be used to authenticate future requests to the identity server. + */ + @Json(name = "token") + val token: String +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRequestOwnershipParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRequestOwnershipParams.kt new file mode 100644 index 0000000000..d3f4778d7f --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/model/IdentityRequestOwnershipParams.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.matrix.android.internal.session.identity.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class IdentityRequestOwnershipParams( + @Json(name = "client_secret") + var clientSecret: String? = null, + + @Json(name = "sid") + var sid: String? = null, + + @Json(name = "token") + var token: String? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataDataSource.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataDataSource.kt new file mode 100644 index 0000000000..37b0da9101 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataDataSource.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.todelete + +import androidx.lifecycle.LiveData +import androidx.lifecycle.Transformations +import com.zhuinden.monarchy.Monarchy +import im.vector.matrix.android.api.util.Optional +import im.vector.matrix.android.api.util.toOptional +import im.vector.matrix.android.internal.database.model.UserAccountDataEntity +import im.vector.matrix.android.internal.database.model.UserAccountDataEntityFields +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import io.realm.Realm +import io.realm.RealmQuery +import javax.inject.Inject + +// There will be a duplicated class when Integration manager will be merged, so delete this one +internal class AccountDataDataSource @Inject constructor(private val monarchy: Monarchy, + private val accountDataMapper: AccountDataMapper) { + + fun getAccountDataEvent(type: String): UserAccountDataEvent? { + return getAccountDataEvents(setOf(type)).firstOrNull() + } + + fun getLiveAccountDataEvent(type: String): LiveData> { + return Transformations.map(getLiveAccountDataEvents(setOf(type))) { + it.firstOrNull()?.toOptional() + } + } + + fun getAccountDataEvents(types: Set): List { + return monarchy.fetchAllMappedSync( + { accountDataEventsQuery(it, types) }, + accountDataMapper::map + ) + } + + fun getLiveAccountDataEvents(types: Set): LiveData> { + return monarchy.findAllMappedWithChanges( + { accountDataEventsQuery(it, types) }, + accountDataMapper::map + ) + } + + private fun accountDataEventsQuery(realm: Realm, types: Set): RealmQuery { + val query = realm.where(UserAccountDataEntity::class.java) + if (types.isNotEmpty()) { + query.`in`(UserAccountDataEntityFields.TYPE, types.toTypedArray()) + } + return query + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataMapper.kt new file mode 100644 index 0000000000..4627911b72 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/AccountDataMapper.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.todelete + +import com.squareup.moshi.Moshi +import im.vector.matrix.android.api.util.JSON_DICT_PARAMETERIZED_TYPE +import im.vector.matrix.android.internal.database.model.UserAccountDataEntity +import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent +import javax.inject.Inject + +// There will be a duplicated class when Integration manager will be merged, so delete this one +internal class AccountDataMapper @Inject constructor(moshi: Moshi) { + + private val adapter = moshi.adapter>(JSON_DICT_PARAMETERIZED_TYPE) + + fun map(entity: UserAccountDataEntity): UserAccountDataEvent { + return UserAccountDataEvent( + type = entity.type ?: "", + content = entity.contentStr?.let { adapter.fromJson(it) } ?: emptyMap() + ) + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/LiveData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/LiveData.kt new file mode 100644 index 0000000000..f84756fa86 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/todelete/LiveData.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.identity.todelete + +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer + +// There will be a duplicated class when Integration manager will be merged, so delete this one +inline fun LiveData.observeK(owner: LifecycleOwner, crossinline observer: (T?) -> Unit) { + this.observe(owner, Observer { observer(it) }) +} + +inline fun LiveData.observeNotNull(owner: LifecycleOwner, crossinline observer: (T) -> Unit) { + this.observe(owner, Observer { it?.run(observer) }) +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt index c508413665..e7a7939540 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt @@ -30,5 +30,6 @@ abstract class UserAccountData : AccountDataContent { const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls" const val TYPE_WIDGETS = "m.widgets" const val TYPE_PUSH_RULES = "m.push_rules" + const val TYPE_IDENTITY = "m.identity" } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt new file mode 100644 index 0000000000..4777daf591 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.session.sync.model.accountdata + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class UserAccountDataIdentity( + @Json(name = "type") override val type: String = TYPE_IDENTITY, + @Json(name = "content") val content: IdentityContent? = null +) : UserAccountData() + +@JsonClass(generateAdapter = true) +internal data class IdentityContent( + @Json(name = "base_url") val baseUrl: String? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index beb3a0fcc0..7daeef699e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.user.accountdata import im.vector.matrix.android.internal.di.UserId import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.sync.model.accountdata.BreadcrumbsContent +import im.vector.matrix.android.internal.session.sync.model.accountdata.IdentityContent import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus @@ -31,6 +32,15 @@ internal interface UpdateUserAccountDataTask : Task> From 0199cf9a037e224924c1cba5a3083f8523c8d37a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 14:49:47 +0200 Subject: [PATCH 134/199] Identity - Fix issue with Realm --- .../internal/session/identity/BulkLookupTask.kt | 2 +- .../session/identity/DefaultIdentityService.kt | 6 +++--- .../identity/IdentityAccessTokenProvider.kt | 2 +- .../session/identity/db/IdentityServerQuery.kt | 6 +++++- .../session/identity/db/IdentityServiceStore.kt | 2 +- .../identity/db/RealmIdentityServerStore.kt | 16 +++++++++++----- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt index 9d701ad7c5..0524e704f3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/BulkLookupTask.kt @@ -43,7 +43,7 @@ internal class DefaultBulkLookupTask @Inject constructor( override suspend fun execute(params: BulkLookupTask.Params): List { val identityAPI = identityApiProvider.identityApi ?: throw IdentityServiceError.NoIdentityServerConfigured - val entity = identityServiceStore.get() + val entity = identityServiceStore.get() ?: throw IdentityServiceError.NoIdentityServerConfigured val pepper = entity.hashLookupPepper val hashDetailResponse = if (pepper == null) { // We need to fetch the hash details first diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt index f02e5446d8..01f2c466ac 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -90,7 +90,7 @@ internal class DefaultIdentityService @Inject constructor( private fun notifyIdentityServerUrlChange(baseUrl: String?) { // This is maybe not a real change (local echo of account data we are just setting - if (identityServiceStore.get().identityServerUrl == baseUrl) { + if (identityServiceStore.get()?.identityServerUrl == baseUrl) { Timber.d("Local echo of identity server url change") } else { // Url has changed, we have to reset our store, update internal configuration and notify listeners @@ -109,7 +109,7 @@ internal class DefaultIdentityService @Inject constructor( } override fun getCurrentIdentityServer(): String? { - return identityServiceStore.get().identityServerUrl + return identityServiceStore.get()?.identityServerUrl } override fun disconnect() { @@ -176,7 +176,7 @@ internal class DefaultIdentityService @Inject constructor( } private suspend fun ensureToken() { - val entity = identityServiceStore.get() + val entity = identityServiceStore.get() ?: throw IdentityServiceError.NoIdentityServerConfigured val url = entity.identityServerUrl ?: throw IdentityServiceError.NoIdentityServerConfigured if (entity.token == null) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt index 2fe2ca033b..1a7c724892 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/IdentityAccessTokenProvider.kt @@ -23,5 +23,5 @@ import javax.inject.Inject internal class IdentityAccessTokenProvider @Inject constructor( private val identityServiceStore: IdentityServiceStore ) : AccessTokenProvider { - override fun getToken() = identityServiceStore.get().token + override fun getToken() = identityServiceStore.get()?.token } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt index 6bef6109c3..7b7bec13c0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServerQuery.kt @@ -24,8 +24,12 @@ import io.realm.kotlin.where /** * Only one object can be stored at a time */ +internal fun IdentityServerEntity.Companion.get(realm: Realm): IdentityServerEntity? { + return realm.where().findFirst() +} + internal fun IdentityServerEntity.Companion.getOrCreate(realm: Realm): IdentityServerEntity { - return realm.where().findFirst() ?: realm.createObject() + return get(realm) ?: realm.createObject() } internal fun IdentityServerEntity.Companion.setUrl(realm: Realm, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt index 6933f0284f..af44766631 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/IdentityServiceStore.kt @@ -20,7 +20,7 @@ import im.vector.matrix.android.internal.session.identity.model.IdentityHashDeta internal interface IdentityServiceStore { - fun get(): IdentityServerEntity + fun get(): IdentityServerEntity? fun setUrl(url: String?) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt index 96194b3dcd..2c7ffbd75f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/db/RealmIdentityServerStore.kt @@ -27,27 +27,33 @@ internal class RealmIdentityServerStore @Inject constructor( private val realmConfiguration: RealmConfiguration ) : IdentityServiceStore { - override fun get(): IdentityServerEntity { + override fun get(): IdentityServerEntity? { return Realm.getInstance(realmConfiguration).use { - IdentityServerEntity.getOrCreate(it) + IdentityServerEntity.get(it) } } override fun setUrl(url: String?) { Realm.getInstance(realmConfiguration).use { - IdentityServerEntity.setUrl(it, url) + it.executeTransaction { realm -> + IdentityServerEntity.setUrl(realm, url) + } } } override fun setToken(token: String?) { Realm.getInstance(realmConfiguration).use { - IdentityServerEntity.setToken(it, token) + it.executeTransaction { realm -> + IdentityServerEntity.setToken(realm, token) + } } } override fun setHashDetails(hashDetailResponse: IdentityHashDetailResponse) { Realm.getInstance(realmConfiguration).use { - IdentityServerEntity.setHashDetails(it, hashDetailResponse.pepper, hashDetailResponse.algorithms) + it.executeTransaction { realm -> + IdentityServerEntity.setHashDetails(realm, hashDetailResponse.pepper, hashDetailResponse.algorithms) + } } } } From 784918350b21f72bc44cc48efc2d63f6333441a6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 6 May 2020 23:34:26 +0200 Subject: [PATCH 135/199] Identity: import UI/UX From Riot and adapt to RiotX architecture --- .../api/session/identity/IdentityService.kt | 8 +- .../android/api/session/identity/ThreePid.kt | 2 +- .../identity/DefaultIdentityService.kt | 68 ++- .../sync/model/accountdata/UserAccountData.kt | 2 +- .../accountdata/UserAccountDataIdentity.kt | 2 +- .../accountdata/UpdateUserAccountDataTask.kt | 2 +- .../im/vector/riotx/core/di/FragmentModule.kt | 12 + .../vector/riotx/core/di/ViewModelModule.kt | 6 + .../discovery/DiscoverySettingsController.kt | 303 +++++++++++ .../discovery/DiscoverySettingsFragment.kt | 199 +++++++ .../discovery/DiscoverySettingsViewModel.kt | 503 ++++++++++++++++++ .../discovery/DiscoverySharedViewModel.kt | 35 ++ .../features/discovery/SettingsButtonItem.kt | 71 +++ .../features/discovery/SettingsImageItem.kt | 70 +++ .../features/discovery/SettingsInfoItem.kt | 70 +++ .../riotx/features/discovery/SettingsItem.kt | 83 +++ .../features/discovery/SettingsItemText.kt | 76 +++ .../features/discovery/SettingsLoadingItem.kt | 44 ++ .../discovery/SettingsSectionTitle.kt | 50 ++ .../discovery/SettingsTextButtonItem.kt | 173 ++++++ .../change/SetIdentityServerFragment.kt | 170 ++++++ .../change/SetIdentityServerViewModel.kt | 171 ++++++ .../settings/VectorSettingsGeneralFragment.kt | 3 +- .../ic_notification_privacy_warning.png | Bin 0 -> 2165 bytes .../layout/fragment_set_identity_server.xml | 52 ++ .../main/res/layout/item_settings_button.xml | 15 + .../item_settings_button_single_line.xml | 86 +++ .../res/layout/item_settings_edit_text.xml | 56 ++ .../res/layout/item_settings_helper_info.xml | 15 + .../item_settings_radio_single_line.xml | 40 ++ .../layout/item_settings_section_title.xml | 15 + .../res/layout/item_settings_simple_item.xml | 47 ++ .../res/menu/menu_phone_number_addition.xml | 11 + vector/src/main/res/values/colors_riot.xml | 1 + .../main/res/xml/vector_settings_general.xml | 9 +- 35 files changed, 2440 insertions(+), 30 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsController.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsFragment.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsViewModel.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySharedViewModel.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsButtonItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsImageItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsInfoItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsItemText.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsLoadingItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsSectionTitle.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/SettingsTextButtonItem.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/change/SetIdentityServerFragment.kt create mode 100644 vector/src/main/java/im/vector/riotx/features/discovery/change/SetIdentityServerViewModel.kt create mode 100644 vector/src/main/res/drawable-xxhdpi/ic_notification_privacy_warning.png create mode 100644 vector/src/main/res/layout/fragment_set_identity_server.xml create mode 100644 vector/src/main/res/layout/item_settings_button.xml create mode 100644 vector/src/main/res/layout/item_settings_button_single_line.xml create mode 100644 vector/src/main/res/layout/item_settings_edit_text.xml create mode 100644 vector/src/main/res/layout/item_settings_helper_info.xml create mode 100644 vector/src/main/res/layout/item_settings_radio_single_line.xml create mode 100644 vector/src/main/res/layout/item_settings_section_title.xml create mode 100644 vector/src/main/res/layout/item_settings_simple_item.xml create mode 100644 vector/src/main/res/menu/menu_phone_number_addition.xml diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt index 0a844d0921..668cae5e00 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt @@ -27,7 +27,7 @@ interface IdentityService { /** * Return the default identity server of the homeserver (using Wellknown request) */ - fun getDefaultIdentityServer(): String? + fun getDefaultIdentityServer(callback: MatrixCallback): Cancelable fun getCurrentIdentityServer(): String? @@ -35,9 +35,11 @@ interface IdentityService { fun disconnect() - fun bindThreePid() + fun startBindSession(threePid: ThreePid, nothing: Nothing?, matrixCallback: MatrixCallback) + fun finalizeBindSessionFor3PID(threePid: ThreePid, matrixCallback: MatrixCallback) + fun submitValidationToken(pid: ThreePid, code: String, matrixCallback: MatrixCallback) - fun unbindThreePid() + fun startUnBindSession(threePid: ThreePid, nothing: Nothing?, matrixCallback: MatrixCallback>) fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt index 7aabb2b9e0..2fa97492fd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/ThreePid.kt @@ -18,5 +18,5 @@ package im.vector.matrix.android.api.session.identity sealed class ThreePid(open val value: String) { data class Email(val email: String) : ThreePid(email) - data class Msisdn(val msisdn: String) : ThreePid(msisdn) + data class Msisdn(val msisdn: String, val countryCode: String? = null) : ThreePid(msisdn) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt index 01f2c466ac..5a4a66a722 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.identity.IdentityServiceError import im.vector.matrix.android.api.session.identity.IdentityServiceListener import im.vector.matrix.android.api.session.identity.ThreePid import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.api.util.NoOpCancellable import im.vector.matrix.android.internal.di.AuthenticatedIdentity import im.vector.matrix.android.internal.di.Unauthenticated import im.vector.matrix.android.internal.network.RetrofitFactory @@ -78,7 +79,7 @@ internal class DefaultIdentityService @Inject constructor( lifecycleRegistry.currentState = Lifecycle.State.STARTED // Observe the account data change accountDataDataSource - .getLiveAccountDataEvent(UserAccountData.TYPE_IDENTITY) + .getLiveAccountDataEvent(UserAccountData.TYPE_IDENTITY_SERVER) .observeNotNull(lifecycleOwner) { val identityServerContent = it.getOrNull()?.content?.toModel() if (identityServerContent != null) { @@ -104,8 +105,10 @@ internal class DefaultIdentityService @Inject constructor( lifecycleRegistry.currentState = Lifecycle.State.DESTROYED } - override fun getDefaultIdentityServer(): String? { - TODO("Not yet implemented") + override fun getDefaultIdentityServer(callback: MatrixCallback): Cancelable { + // TODO Use Wellknown request + callback.onSuccess("https://vector.im") + return NoOpCancellable } override fun getCurrentIdentityServer(): String? { @@ -116,22 +119,49 @@ internal class DefaultIdentityService @Inject constructor( TODO("Not yet implemented") } + override fun startBindSession(threePid: ThreePid, nothing: Nothing?, matrixCallback: MatrixCallback) { + TODO("Not yet implemented") + } + + override fun finalizeBindSessionFor3PID(threePid: ThreePid, matrixCallback: MatrixCallback) { + TODO("Not yet implemented") + } + + override fun submitValidationToken(pid: ThreePid, code: String, matrixCallback: MatrixCallback) { + TODO("Not yet implemented") + } + + override fun startUnBindSession(threePid: ThreePid, nothing: Nothing?, matrixCallback: MatrixCallback>) { + TODO("Not yet implemented") + } + override fun setNewIdentityServer(url: String?, callback: MatrixCallback): Cancelable { + val urlCandidate = url?.let { param -> + buildString { + if (!param.startsWith("http")) { + append("https://") + } + append(param) + } + } + return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { val current = getCurrentIdentityServer() - when (url) { + when (urlCandidate) { current -> // Nothing to do Timber.d("Same URL, nothing to do") null -> { - // TODO - // Disconnect previous one if any + // TODO Disconnect previous one if any identityServiceStore.setUrl(null) updateAccountData(null) } else -> { // TODO: check first that it is a valid identity server - updateAccountData(url) + // Try to get a token + getIdentityServerToken(urlCandidate) + + updateAccountData(urlCandidate) } } } @@ -143,14 +173,6 @@ internal class DefaultIdentityService @Inject constructor( )) } - override fun bindThreePid() { - TODO("Not yet implemented") - } - - override fun unbindThreePid() { - TODO("Not yet implemented") - } - override fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable { return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) { lookUpInternal(true, threePids) @@ -181,15 +203,19 @@ internal class DefaultIdentityService @Inject constructor( if (entity.token == null) { // Try to get a token - val openIdToken = openIdTokenTask.execute(Unit) - - val api = retrofitFactory.create(unauthenticatedOkHttpClient, url).create(IdentityAuthAPI::class.java) - val token = identityRegisterTask.execute(IdentityRegisterTask.Params(api, openIdToken)) - - identityServiceStore.setToken(token.token) + getIdentityServerToken(url) } } + private suspend fun getIdentityServerToken(url: String) { + val api = retrofitFactory.create(unauthenticatedOkHttpClient, url).create(IdentityAuthAPI::class.java) + + val openIdToken = openIdTokenTask.execute(Unit) + val token = identityRegisterTask.execute(IdentityRegisterTask.Params(api, openIdToken)) + + identityServiceStore.setToken(token.token) + } + override fun addListener(listener: IdentityServiceListener) { listeners.add(listener) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt index e7a7939540..ce46d3ba77 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountData.kt @@ -30,6 +30,6 @@ abstract class UserAccountData : AccountDataContent { const val TYPE_PREVIEW_URLS = "org.matrix.preview_urls" const val TYPE_WIDGETS = "m.widgets" const val TYPE_PUSH_RULES = "m.push_rules" - const val TYPE_IDENTITY = "m.identity" + const val TYPE_IDENTITY_SERVER = "m.identity_server" } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt index 4777daf591..354022420e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/model/accountdata/UserAccountDataIdentity.kt @@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) internal data class UserAccountDataIdentity( - @Json(name = "type") override val type: String = TYPE_IDENTITY, + @Json(name = "type") override val type: String = TYPE_IDENTITY_SERVER, @Json(name = "content") val content: IdentityContent? = null ) : UserAccountData() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt index 7daeef699e..01dc297946 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/user/accountdata/UpdateUserAccountDataTask.kt @@ -32,7 +32,7 @@ internal interface UpdateUserAccountDataTask : Task() { + + var listener: Listener? = null + + override fun buildModels(data: DiscoverySettingsState) { + when (data.identityServer) { + is Loading -> { + settingsLoadingItem { + id("identityServerLoading") + } + } + is Fail -> { + settingsInfoItem { + id("identityServerError") + helperText(data.identityServer.error.message) + } + } + is Success -> { + buildIdentityServerSection(data) + + val hasIdentityServer = data.identityServer().isNullOrBlank().not() + + if (hasIdentityServer) { + buildMailSection(data) + buildPhoneNumberSection(data) + } + } + } + } + + private fun buildPhoneNumberSection(data: DiscoverySettingsState) { + settingsSectionTitle { + id("msisdn") + titleResId(R.string.settings_discovery_msisdn_title) + } + + when (data.phoneNumbersList) { + is Loading -> { + settingsLoadingItem { + id("phoneLoading") + } + } + is Fail -> { + settingsInfoItem { + id("msisdnListError") + helperText(data.phoneNumbersList.error.message) + } + } + is Success -> { + val phones = data.phoneNumbersList.invoke() + if (phones.isEmpty()) { + settingsInfoItem { + id("no_msisdn") + helperText(stringProvider.getString(R.string.settings_discovery_no_msisdn)) + } + } else { + phones.forEach { piState -> + val phoneNumber = PhoneNumberUtil.getInstance() + .parse("+${piState.value}", null) + ?.let { + PhoneNumberUtil.getInstance().format(it, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL) + } + + settingsTextButtonItem { + id(piState.value) + title(phoneNumber) + colorProvider(colorProvider) + stringProvider(stringProvider) + when { + piState.isShared is Loading -> buttonIndeterminate(true) + piState.isShared is Fail -> { + buttonType(SettingsTextButtonItem.ButtonType.NORMAL) + buttonStyle(SettingsTextButtonItem.ButtonStyle.DESTRUCTIVE) + buttonTitle(stringProvider.getString(R.string.global_retry)) + infoMessage(piState.isShared.error.message) + buttonClickListener(View.OnClickListener { + listener?.onTapRetryToRetrieveBindings() + }) + } + piState.isShared is Success -> when (piState.isShared()) { + PidInfo.SharedState.SHARED, + PidInfo.SharedState.NOT_SHARED -> { + checked(piState.isShared() == PidInfo.SharedState.SHARED) + buttonType(SettingsTextButtonItem.ButtonType.SWITCH) + switchChangeListener { _, checked -> + if (checked) { + listener?.onTapShareMsisdn(piState.value) + } else { + listener?.onTapRevokeMsisdn(piState.value) + } + } + } + PidInfo.SharedState.NOT_VERIFIED_FOR_BIND, + PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND -> { + buttonType(SettingsTextButtonItem.ButtonType.NORMAL) + buttonTitle("") + } + } + } + } + when (piState.isShared()) { + PidInfo.SharedState.NOT_VERIFIED_FOR_BIND, + PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND -> { + settingsItemText { + id("tverif" + piState.value) + descriptionText(stringProvider.getString(R.string.settings_text_message_sent, phoneNumber)) + interactionListener(object : SettingsItemText.Listener { + override fun onValidate(code: String) { + val bind = piState.isShared() == PidInfo.SharedState.NOT_VERIFIED_FOR_BIND + listener?.checkMsisdnVerification(piState.value, code, bind) + } + }) + } + } + else -> { + } + } + } + } + } + } + } + + private fun buildMailSection(data: DiscoverySettingsState) { + settingsSectionTitle { + id("emails") + titleResId(R.string.settings_discovery_emails_title) + } + when (data.emailList) { + is Loading -> { + settingsLoadingItem { + id("mailLoading") + } + } + is Fail -> { + settingsInfoItem { + id("mailListError") + helperText(data.emailList.error.message) + } + } + is Success -> { + val emails = data.emailList.invoke() + if (emails.isEmpty()) { + settingsInfoItem { + id("no_emails") + helperText(stringProvider.getString(R.string.settings_discovery_no_mails)) + } + } else { + emails.forEach { piState -> + settingsTextButtonItem { + id(piState.value) + title(piState.value) + colorProvider(colorProvider) + stringProvider(stringProvider) + when (piState.isShared) { + is Loading -> buttonIndeterminate(true) + is Fail -> { + buttonType(SettingsTextButtonItem.ButtonType.NORMAL) + buttonStyle(SettingsTextButtonItem.ButtonStyle.DESTRUCTIVE) + buttonTitle(stringProvider.getString(R.string.global_retry)) + infoMessage(piState.isShared.error.message) + buttonClickListener(View.OnClickListener { + listener?.onTapRetryToRetrieveBindings() + }) + } + is Success -> when (piState.isShared()) { + PidInfo.SharedState.SHARED, + PidInfo.SharedState.NOT_SHARED -> { + checked(piState.isShared() == PidInfo.SharedState.SHARED) + buttonType(SettingsTextButtonItem.ButtonType.SWITCH) + switchChangeListener { _, checked -> + if (checked) { + listener?.onTapShareEmail(piState.value) + } else { + listener?.onTapRevokeEmail(piState.value) + } + } + } + PidInfo.SharedState.NOT_VERIFIED_FOR_BIND, + PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND -> { + buttonType(SettingsTextButtonItem.ButtonType.NORMAL) + buttonTitleId(R.string._continue) + infoMessageTintColorId(R.color.vector_info_color) + infoMessage(stringProvider.getString(R.string.settings_discovery_confirm_mail, piState.value)) + buttonClickListener(View.OnClickListener { + val bind = piState.isShared() == PidInfo.SharedState.NOT_VERIFIED_FOR_BIND + listener?.checkEmailVerification(piState.value, bind) + }) + } + } + } + } + } + } + } + } + } + + private fun buildIdentityServerSection(data: DiscoverySettingsState) { + val identityServer = data.identityServer() ?: stringProvider.getString(R.string.none) + + settingsSectionTitle { + id("idsTitle") + titleResId(R.string.identity_server) + } + + settingsItem { + id("idServer") + description(identityServer) + } + + settingsInfoItem { + id("idServerFooter") + if (data.termsNotSigned) { + helperText(stringProvider.getString(R.string.settings_agree_to_terms, identityServer)) + showCompoundDrawable(true) + itemClickListener(View.OnClickListener { listener?.onSelectIdentityServer() }) + } else { + showCompoundDrawable(false) + if (data.identityServer() != null) { + helperText(stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServer)) + } else { + helperTextResId(R.string.settings_discovery_identity_server_info_none) + } + } + } + + settingsButtonItem { + id("change") + colorProvider(colorProvider) + if (data.identityServer() != null) { + buttonTitleId(R.string.change_identity_server) + } else { + buttonTitleId(R.string.add_identity_server) + } + buttonStyle(SettingsTextButtonItem.ButtonStyle.POSITIVE) + buttonClickListener(View.OnClickListener { + listener?.onTapChangeIdentityServer() + }) + } + + if (data.identityServer() != null) { + settingsInfoItem { + id("removeInfo") + helperTextResId(R.string.settings_discovery_disconnect_identity_server_info) + } + settingsButtonItem { + id("remove") + colorProvider(colorProvider) + buttonTitleId(R.string.disconnect_identity_server) + buttonStyle(SettingsTextButtonItem.ButtonStyle.DESTRUCTIVE) + buttonClickListener(View.OnClickListener { + listener?.onTapDisconnectIdentityServer() + }) + } + } + } + + interface Listener { + fun onSelectIdentityServer() + fun onTapRevokeEmail(email: String) + fun onTapShareEmail(email: String) + fun checkEmailVerification(email: String, bind: Boolean) + fun checkMsisdnVerification(msisdn: String, code: String, bind: Boolean) + fun onTapRevokeMsisdn(msisdn: String) + fun onTapShareMsisdn(msisdn: String) + fun onTapChangeIdentityServer() + fun onTapDisconnectIdentityServer() + fun onTapRetryToRetrieveBindings() + } +} + diff --git a/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsFragment.kt new file mode 100644 index 0000000000..bdf0ca6de4 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsFragment.kt @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.riotx.features.discovery + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.Observer +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import im.vector.matrix.android.api.session.identity.ThreePid +import im.vector.riotx.R +import im.vector.riotx.core.extensions.cleanup +import im.vector.riotx.core.extensions.configureWith +import im.vector.riotx.core.extensions.exhaustive +import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.discovery.change.SetIdentityServerFragment +import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import javax.inject.Inject + +class DiscoverySettingsFragment @Inject constructor( + private val controller: DiscoverySettingsController, + val viewModelFactory: DiscoverySettingsViewModel.Factory +) : VectorBaseFragment(), DiscoverySettingsController.Listener { + + override fun getLayoutResId() = R.layout.fragment_generic_recycler + + private val viewModel by fragmentViewModel(DiscoverySettingsViewModel::class) + + lateinit var sharedViewModel: DiscoverySharedViewModel + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + sharedViewModel = activityViewModelProvider.get(DiscoverySharedViewModel::class.java) + + controller.listener = this + recyclerView.configureWith(controller) + + sharedViewModel.navigateEvent.observe(viewLifecycleOwner, Observer { + if (it.peekContent().first == DiscoverySharedViewModel.NEW_IDENTITY_SERVER_SET_REQUEST) { + viewModel.handle(DiscoverySettingsAction.ChangeIdentityServer(it.peekContent().second)) + } + }) + + viewModel.observeViewEvents { + when (it) { + is DiscoverySettingsViewEvents.Failure -> { + // TODO Snackbar.make(view, throwable.toString(), Snackbar.LENGTH_LONG).show() + } + }.exhaustive + } + } + + override fun onDestroyView() { + recyclerView.cleanup() + controller.listener = null + super.onDestroyView() + } + + override fun invalidate() = withState(viewModel) { state -> + controller.setData(state) + } + + override fun onResume() { + super.onResume() + (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_discovery_category) + + //If some 3pids are pending, we can try to check if they have been verified here + viewModel.handle(DiscoverySettingsAction.Refresh) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + /* TODO + if (requestCode == TERMS_REQUEST_CODE) { + if (Activity.RESULT_OK == resultCode) { + viewModel.refreshModel() + } else { + //add some error? + } + } + + */ + super.onActivityResult(requestCode, resultCode, data) + } + + override fun onSelectIdentityServer() = withState(viewModel) { state -> + if (state.termsNotSigned) { + /* + TODO + ReviewTermsActivity.intent(requireContext(), + TermsManager.ServiceType.IdentityService, + SetIdentityServerViewModel.sanitatizeBaseURL(state.identityServer() ?: ""), + null).also { + startActivityForResult(it, TERMS_REQUEST_CODE) + } + + */ + } + } + + override fun onTapRevokeEmail(email: String) { + viewModel.handle(DiscoverySettingsAction.RevokeThreePid(ThreePid.Email(email))) + } + + override fun onTapShareEmail(email: String) { + viewModel.handle(DiscoverySettingsAction.ShareThreePid(ThreePid.Email(email))) + } + + override fun checkEmailVerification(email: String, bind: Boolean) { + viewModel.handle(DiscoverySettingsAction.FinalizeBind3pid(ThreePid.Email(email), bind)) + } + + override fun checkMsisdnVerification(msisdn: String, code: String, bind: Boolean) { + viewModel.handle(DiscoverySettingsAction.SubmitMsisdnToken(msisdn, code, bind)) + } + + override fun onTapRevokeMsisdn(msisdn: String) { + viewModel.handle(DiscoverySettingsAction.RevokeThreePid(ThreePid.Msisdn(msisdn))) + } + + override fun onTapShareMsisdn(msisdn: String) { + viewModel.handle(DiscoverySettingsAction.ShareThreePid(ThreePid.Msisdn(msisdn))) + } + + override fun onTapChangeIdentityServer() = withState(viewModel) { state -> + //we should prompt if there are bound items with current is + val pidList = ArrayList().apply { + state.emailList()?.let { addAll(it) } + state.phoneNumbersList()?.let { addAll(it) } + } + + val hasBoundIds = pidList.any { it.isShared() == PidInfo.SharedState.SHARED } + + if (hasBoundIds) { + //we should prompt + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.change_identity_server) + .setMessage(getString(R.string.settings_discovery_disconnect_with_bound_pid, state.identityServer(), state.identityServer())) + .setPositiveButton(R.string._continue) { _, _ -> navigateToChangeIdentityServerFragment() } + .setNegativeButton(R.string.cancel, null) + .show() + Unit + } else { + navigateToChangeIdentityServerFragment() + } + } + + override fun onTapDisconnectIdentityServer() { + //we should prompt if there are bound items with current is + withState(viewModel) { state -> + val pidList = ArrayList().apply { + state.emailList()?.let { addAll(it) } + state.phoneNumbersList()?.let { addAll(it) } + } + + val hasBoundIds = pidList.any { it.isShared() == PidInfo.SharedState.SHARED } + + if (hasBoundIds) { + //we should prompt + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.disconnect_identity_server) + .setMessage(getString(R.string.settings_discovery_disconnect_with_bound_pid, state.identityServer(), state.identityServer())) + .setPositiveButton(R.string._continue) { _, _ -> viewModel.handle(DiscoverySettingsAction.ChangeIdentityServer(null)) } + .setNegativeButton(R.string.cancel, null) + .show() + } else { + viewModel.handle(DiscoverySettingsAction.ChangeIdentityServer(null)) + } + } + } + + override fun onTapRetryToRetrieveBindings() { + viewModel.handle(DiscoverySettingsAction.RetrieveBinding) + } + + private fun navigateToChangeIdentityServerFragment() { + parentFragmentManager.beginTransaction() + .setCustomAnimations(R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom, R.anim.anim_slide_in_bottom, R.anim.anim_slide_out_bottom) + .replace(R.id.vector_settings_page, SetIdentityServerFragment::class.java, null) + .addToBackStack(null) + .commit() + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsViewModel.kt new file mode 100644 index 0000000000..34c5bcf66b --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySettingsViewModel.kt @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.riotx.features.discovery + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.Fail +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Success +import com.airbnb.mvrx.Uninitialized +import com.airbnb.mvrx.ViewModelContext +import com.google.i18n.phonenumbers.PhoneNumberUtil +import com.squareup.inject.assisted.Assisted +import com.squareup.inject.assisted.AssistedInject +import im.vector.matrix.android.api.MatrixCallback +import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.api.session.identity.IdentityServiceListener +import im.vector.matrix.android.api.session.identity.ThreePid +import im.vector.riotx.core.extensions.exhaustive +import im.vector.riotx.core.platform.VectorViewEvents +import im.vector.riotx.core.platform.VectorViewModel +import im.vector.riotx.core.platform.VectorViewModelAction + +data class PidInfo( + val value: String, + val isShared: Async, + val _3pid: ThreePid? = null +) { + enum class SharedState { + SHARED, + NOT_SHARED, + NOT_VERIFIED_FOR_BIND, + NOT_VERIFIED_FOR_UNBIND + } +} + +data class DiscoverySettingsState( + val identityServer: Async = Uninitialized, + val emailList: Async> = Uninitialized, + val phoneNumbersList: Async> = Uninitialized, + // TODO Use ViewEvents + val termsNotSigned: Boolean = false +) : MvRxState + +sealed class DiscoverySettingsAction : VectorViewModelAction { + object RetrieveBinding : DiscoverySettingsAction() + object Refresh : DiscoverySettingsAction() + + data class ChangeIdentityServer(val url: String?) : DiscoverySettingsAction() + data class RevokeThreePid(val threePid: ThreePid) : DiscoverySettingsAction() + data class ShareThreePid(val threePid: ThreePid) : DiscoverySettingsAction() + data class FinalizeBind3pid(val threePid: ThreePid, val bind: Boolean) : DiscoverySettingsAction() + data class SubmitMsisdnToken(val msisdn: String, val code: String, val bind: Boolean) : DiscoverySettingsAction() +} + +sealed class DiscoverySettingsViewEvents : VectorViewEvents { + data class Failure(val throwable: Throwable) : DiscoverySettingsViewEvents() +} + +class DiscoverySettingsViewModel @AssistedInject constructor( + @Assisted initialState: DiscoverySettingsState, + private val session: Session) + : VectorViewModel(initialState) { + + @AssistedInject.Factory + interface Factory { + fun create(initialState: DiscoverySettingsState): DiscoverySettingsViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: DiscoverySettingsState): DiscoverySettingsViewModel? { + val fragment: DiscoverySettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() + return fragment.viewModelFactory.create(state) + } + } + + private val identityService = session.identityService() + + private val identityServerManagerListener = object : IdentityServiceListener { + override fun onIdentityServerChange() = withState { state -> + val identityServerUrl = identityService.getCurrentIdentityServer() + val currentIS = state.identityServer() + setState { + copy(identityServer = Success(identityServerUrl)) + } + if (currentIS != identityServerUrl) refreshModel() + } + } + + init { + startListenToIdentityManager() + refreshModel() + } + + override fun onCleared() { + super.onCleared() + stopListenToIdentityManager() + } + + override fun handle(action: DiscoverySettingsAction) { + when (action) { + DiscoverySettingsAction.Refresh -> refreshPendingEmailBindings() + DiscoverySettingsAction.RetrieveBinding -> retrieveBinding() + is DiscoverySettingsAction.ChangeIdentityServer -> changeIdentityServer(action) + is DiscoverySettingsAction.RevokeThreePid -> revokeThreePid(action) + is DiscoverySettingsAction.ShareThreePid -> shareThreePid(action) + is DiscoverySettingsAction.FinalizeBind3pid -> finalizeBind3pid(action) + is DiscoverySettingsAction.SubmitMsisdnToken -> submitMsisdnToken(action) + }.exhaustive + } + + private fun changeIdentityServer(action: DiscoverySettingsAction.ChangeIdentityServer) { + setState { + copy( + identityServer = Loading() + ) + } + + session.identityService().setNewIdentityServer(action.url, object : MatrixCallback { + override fun onSuccess(data: Unit) { + setState { + copy( + identityServer = Success(action.url) + ) + } + refreshModel() + } + + override fun onFailure(failure: Throwable) { + setState { + copy( + identityServer = Fail(failure) + ) + } + } + }) + } + + private fun shareThreePid(action: DiscoverySettingsAction.ShareThreePid) { + when (action.threePid) { + is ThreePid.Email -> shareEmail(action.threePid.email) + is ThreePid.Msisdn -> shareMsisdn(action.threePid.msisdn) + }.exhaustive + } + + private fun shareEmail(email: String) = withState { state -> + if (state.identityServer() == null) return@withState + changeMailState(email, Loading(), null) + + identityService.startBindSession(ThreePid.Email(email), null, + object : MatrixCallback { + override fun onSuccess(data: ThreePid) { + changeMailState(email, Success(PidInfo.SharedState.NOT_VERIFIED_FOR_BIND), data) + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + + changeMailState(email, Fail(failure)) + } + }) + } + + private fun changeMailState(address: String, state: Async, threePid: ThreePid?) { + setState { + val currentMails = emailList() ?: emptyList() + copy(emailList = Success( + currentMails.map { + if (it.value == address) { + it.copy( + _3pid = threePid, + isShared = state + ) + } else { + it + } + } + )) + } + } + + private fun changeMailState(address: String, state: Async) { + setState { + val currentMails = emailList() ?: emptyList() + copy(emailList = Success( + currentMails.map { + if (it.value == address) { + it.copy(isShared = state) + } else { + it + } + } + )) + } + } + + private fun changeMsisdnState(address: String, state: Async, threePid: ThreePid?) { + setState { + val phones = phoneNumbersList() ?: emptyList() + copy(phoneNumbersList = Success( + phones.map { + if (it.value == address) { + it.copy( + _3pid = threePid, + isShared = state + ) + } else { + it + } + } + )) + } + } + + private fun revokeThreePid(action: DiscoverySettingsAction.RevokeThreePid) { + when (action.threePid) { + is ThreePid.Email -> revokeEmail(action.threePid.email) + is ThreePid.Msisdn -> revokeMsisdn(action.threePid.msisdn) + }.exhaustive + } + + private fun revokeEmail(email: String) = withState { state -> + if (state.identityServer() == null) return@withState + if (state.emailList() == null) return@withState + changeMailState(email, Loading()) + + identityService.startUnBindSession(ThreePid.Email(email), null, object : MatrixCallback> { + override fun onSuccess(data: Pair) { + if (data.first) { + // requires mail validation + changeMailState(email, Success(PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND), data.second) + } else { + changeMailState(email, Success(PidInfo.SharedState.NOT_SHARED)) + } + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + + changeMailState(email, Fail(failure)) + } + }) + } + + private fun revokeMsisdn(msisdn: String) = withState { state -> + if (state.identityServer() == null) return@withState + if (state.emailList() == null) return@withState + changeMsisdnState(msisdn, Loading()) + + val phoneNumber = PhoneNumberUtil.getInstance() + .parse("+$msisdn", null) + val countryCode = PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(phoneNumber.countryCode) + + identityService.startUnBindSession(ThreePid.Msisdn(msisdn, countryCode), null, object : MatrixCallback> { + override fun onSuccess(data: Pair) { + if (data.first /*requires mail validation */) { + changeMsisdnState(msisdn, Success(PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND), data.second) + } else { + changeMsisdnState(msisdn, Success(PidInfo.SharedState.NOT_SHARED)) + } + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + + changeMsisdnState(msisdn, Fail(failure)) + } + }) + + } + + private fun shareMsisdn(msisdn: String) = withState { state -> + if (state.identityServer() == null) return@withState + changeMsisdnState(msisdn, Loading()) + + val phoneNumber = PhoneNumberUtil.getInstance() + .parse("+$msisdn", null) + val countryCode = PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(phoneNumber.countryCode) + + + identityService.startBindSession(ThreePid.Msisdn(msisdn, countryCode), null, object : MatrixCallback { + override fun onSuccess(data: ThreePid) { + changeMsisdnState(msisdn, Success(PidInfo.SharedState.NOT_VERIFIED_FOR_BIND), data) + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + + changeMsisdnState(msisdn, Fail(failure)) + } + }) + } + + private fun changeMsisdnState(msisdn: String, sharedState: Async) { + setState { + val currentMsisdns = phoneNumbersList()!! + copy(phoneNumbersList = Success( + currentMsisdns.map { + if (it.value == msisdn) { + it.copy(isShared = sharedState) + } else { + it + } + }) + ) + } + } + + private fun startListenToIdentityManager() { + identityService.addListener(identityServerManagerListener) + } + + private fun stopListenToIdentityManager() { + identityService.addListener(identityServerManagerListener) + } + + private fun refreshModel() = withState { state -> + if (state.identityServer().isNullOrBlank()) return@withState + + setState { + copy( + emailList = Loading(), + phoneNumbersList = Loading() + ) + } + + /* TODO + session.refreshThirdPartyIdentifiers(object : MatrixCallback { + override fun onFailure(failure: Throwable) { + _errorLiveEvent.postValue(LiveEvent(failure)) + + setState { + copy( + emailList = Fail(failure), + phoneNumbersList = Fail(failure) + ) + } + } + + override fun onSuccess(data: Unit) { + setState { + copy(termsNotSigned = false) + } + + retrieveBinding() + } + }) + */ + } + + private fun retrieveBinding() { + /* TODO + val linkedMailsInfo = session.myUser.getlinkedEmails() + val knownEmails = linkedMailsInfo.map { it.address } + // Note: it will be a list of "email" + val knownEmailMedium = linkedMailsInfo.map { it.medium } + + val linkedMsisdnsInfo = session.myUser.getlinkedPhoneNumbers() + val knownMsisdns = linkedMsisdnsInfo.map { it.address } + // Note: it will be a list of "msisdn" + val knownMsisdnMedium = linkedMsisdnsInfo.map { it.medium } + + setState { + copy( + emailList = Success(knownEmails.map { PidInfo(it, Loading()) }), + phoneNumbersList = Success(knownMsisdns.map { PidInfo(it, Loading()) }) + ) + } + + identityService.lookup(knownEmails + knownMsisdns, + knownEmailMedium + knownMsisdnMedium, + object : MatrixCallback> { + override fun onSuccess(data: List) { + setState { + copy( + emailList = Success(toPidInfoList(knownEmails, data.take(knownEmails.size))), + phoneNumbersList = Success(toPidInfoList(knownMsisdns, data.takeLast(knownMsisdns.size))) + ) + } + } + + override fun onUnexpectedError(e: Exception) { + if (e is TermsNotSignedException) { + setState { + // TODO Use ViewEvent + copy(termsNotSigned = true) + } + } + onError(e) + } + + override fun onNetworkError(e: Exception) { + onError(e) + } + + override fun onMatrixError(e: MatrixError) { + onError(Throwable(e.message)) + } + + private fun onError(e: Throwable) { + _errorLiveEvent.postValue(LiveEvent(e)) + + setState { + copy( + emailList = Success(knownEmails.map { PidInfo(it, Fail(e)) }), + phoneNumbersList = Success(knownMsisdns.map { PidInfo(it, Fail(e)) }) + ) + } + } + }) + */ + } + + private fun toPidInfoList(addressList: List, matrixIds: List): List { + return addressList.map { + val hasMatrixId = matrixIds[addressList.indexOf(it)].isNotBlank() + PidInfo( + value = it, + isShared = Success(PidInfo.SharedState.SHARED.takeIf { hasMatrixId } ?: PidInfo.SharedState.NOT_SHARED) + ) + } + } + + private fun submitMsisdnToken(action: DiscoverySettingsAction.SubmitMsisdnToken) = withState { state -> + val pid = state.phoneNumbersList()?.find { it.value == action.msisdn }?._3pid ?: return@withState + + identityService.submitValidationToken(pid, + action.code, + object : MatrixCallback { + override fun onSuccess(data: Unit) { + finalizeBind3pid(DiscoverySettingsAction.FinalizeBind3pid(ThreePid.Msisdn(action.msisdn), action.bind)) + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + changeMsisdnState(action.msisdn, Fail(failure)) + } + } + ) + } + + private fun finalizeBind3pid(action: DiscoverySettingsAction.FinalizeBind3pid) = withState { state -> + val _3pid = when (action.threePid) { + is ThreePid.Email -> { + changeMailState(action.threePid.email, Loading()) + state.emailList()?.find { it.value == action.threePid.email }?._3pid ?: return@withState + } + is ThreePid.Msisdn -> { + changeMsisdnState(action.threePid.msisdn, Loading()) + state.phoneNumbersList()?.find { it.value == action.threePid.msisdn }?._3pid ?: return@withState + } + } + + identityService.finalizeBindSessionFor3PID(_3pid, object : MatrixCallback { + override fun onSuccess(data: Unit) { + val sharedState = Success(if (action.bind) PidInfo.SharedState.SHARED else PidInfo.SharedState.NOT_SHARED) + when (action.threePid) { + is ThreePid.Email -> changeMailState(action.threePid.email, sharedState, null) + is ThreePid.Msisdn -> changeMsisdnState(action.threePid.msisdn, sharedState, null) + } + } + + override fun onFailure(failure: Throwable) { + _viewEvents.post(DiscoverySettingsViewEvents.Failure(failure)) + + // Restore previous state after an error + val sharedState = Success(if (action.bind) PidInfo.SharedState.NOT_VERIFIED_FOR_BIND else PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND) + when (action.threePid) { + is ThreePid.Email -> changeMailState(action.threePid.email, sharedState) + is ThreePid.Msisdn -> changeMsisdnState(action.threePid.msisdn, sharedState) + } + } + }) + + } + + private fun refreshPendingEmailBindings() = withState { state -> + state.emailList()?.forEach { info -> + when (info.isShared()) { + PidInfo.SharedState.NOT_VERIFIED_FOR_BIND -> finalizeBind3pid(DiscoverySettingsAction.FinalizeBind3pid(ThreePid.Email(info.value), true)) + PidInfo.SharedState.NOT_VERIFIED_FOR_UNBIND -> finalizeBind3pid(DiscoverySettingsAction.FinalizeBind3pid(ThreePid.Email(info.value), false)) + else -> Unit + } + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySharedViewModel.kt new file mode 100644 index 0000000000..91e43187c2 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/discovery/DiscoverySharedViewModel.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.riotx.features.discovery + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import im.vector.riotx.core.utils.LiveEvent +import javax.inject.Inject + +// TODO Rework this +class DiscoverySharedViewModel @Inject constructor() : ViewModel() { + + var navigateEvent = MutableLiveData>>() + + companion object { + const val NEW_IDENTITY_SERVER_SET_REQUEST = "NEW_IDENTITY_SERVER_SET_REQUEST" + } + + fun requestChangeToIdentityServer(server: String) { + navigateEvent.postValue(LiveEvent(NEW_IDENTITY_SERVER_SET_REQUEST to server)) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/discovery/SettingsButtonItem.kt b/vector/src/main/java/im/vector/riotx/features/discovery/SettingsButtonItem.kt new file mode 100644 index 0000000000..8deb500e82 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/discovery/SettingsButtonItem.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.riotx.features.discovery + +import android.view.View +import android.widget.Button +import androidx.annotation.StringRes +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.airbnb.epoxy.EpoxyModelWithHolder +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.VectorEpoxyHolder +import im.vector.riotx.core.extensions.setTextOrHide +import im.vector.riotx.core.resources.ColorProvider + +@EpoxyModelClass(layout = R.layout.item_settings_button) +abstract class SettingsButtonItem : EpoxyModelWithHolder() { + + @EpoxyAttribute + lateinit var colorProvider: ColorProvider + + @EpoxyAttribute + var buttonTitle: String? = null + + @EpoxyAttribute + @StringRes + var buttonTitleId: Int? = null + + @EpoxyAttribute + var buttonStyle: SettingsTextButtonItem.ButtonStyle = SettingsTextButtonItem.ButtonStyle.POSITIVE + + @EpoxyAttribute + var buttonClickListener: View.OnClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + if (buttonTitleId != null) { + holder.button.setText(buttonTitleId!!) + } else { + holder.button.setTextOrHide(buttonTitle) + } + + when (buttonStyle) { + SettingsTextButtonItem.ButtonStyle.POSITIVE -> { + holder.button.setTextColor(colorProvider.getColorFromAttribute(R.attr.colorAccent)) + } + SettingsTextButtonItem.ButtonStyle.DESTRUCTIVE -> { + holder.button.setTextColor(colorProvider.getColor(R.color.vector_error_color)) + } + } + + holder.button.setOnClickListener(buttonClickListener) + } + + class Holder : VectorEpoxyHolder() { + val button by bind