From 008bc0116ddfd8df7c37d137bfd01999740a0539 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Aug 2020 16:36:45 +0200 Subject: [PATCH 001/257] Improve #1971, especially be robust about system time change --- .../sdk/internal/session/call/DefaultCallSignalingService.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt index 6a17f0e925..0b097cf64f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.call +import android.os.SystemClock import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.extensions.tryThis import org.matrix.android.sdk.api.session.call.CallSignalingService @@ -59,10 +60,10 @@ internal class DefaultCallSignalingService @Inject constructor( private val activeCalls = mutableListOf() private val cachedTurnServerResponse = object { - + // Keep one minute safe to avoid considering the data is valid and then actually it is not when effectively using it. private val MIN_TTL = 60 - private val now = { System.currentTimeMillis() / 1000 } + private val now = { SystemClock.elapsedRealtime() / 1000 } private var expiresAt: Long = 0 From 04fa7d962895dc9255d349d643162504d91455ff Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Aug 2020 17:04:05 +0200 Subject: [PATCH 002/257] Version++ --- CHANGES.md | 24 ++++++++++++++++++++++++ vector/build.gradle | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index fb404b971e..2f850c8a3c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,27 @@ +Changes in Element 1.0.6 (2020-XX-XX) +=================================================== + +Features ✨: + - + +Improvements 🙌: + - + +Bugfix 🐛: + - + +Translations 🗣: + - + +SDK API changes ⚠️: + - + +Build 🧱: + - + +Other changes: + - + Changes in Element 1.0.5 (2020-08-21) =================================================== diff --git a/vector/build.gradle b/vector/build.gradle index 57fd0cc51a..1ce5a32817 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -17,7 +17,7 @@ androidExtensions { // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 0 -ext.versionPatch = 5 +ext.versionPatch = 6 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 1f890324b4bc09212191fba155c935fe0869c07c Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Aug 2020 17:17:51 +0200 Subject: [PATCH 003/257] Update some dependencies, including coroutines for working debugging --- matrix-sdk-android/build.gradle | 6 +++--- vector/build.gradle | 12 +++++------- .../settings/VectorSettingsGeneralFragment.kt | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index d98533e4bc..d70b0bbe84 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -112,7 +112,7 @@ dependencies { def moshi_version = '1.8.0' def lifecycle_version = '2.2.0' def arch_version = '2.1.0' - def coroutines_version = "1.3.2" + def coroutines_version = "1.3.8" def markwon_version = '3.1.0' def daggerVersion = '2.25.4' def work_version = '2.3.3' @@ -122,8 +122,8 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" - implementation "androidx.appcompat:appcompat:1.1.0" - implementation "androidx.core:core-ktx:1.3.0" + implementation "androidx.appcompat:appcompat:1.2.0" + implementation "androidx.core:core-ktx:1.3.1" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" diff --git a/vector/build.gradle b/vector/build.gradle index 57fd0cc51a..5738e25b65 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -264,7 +264,7 @@ dependencies { def epoxy_version = '3.11.0' def fragment_version = '1.2.5' def arrow_version = "0.8.2" - def coroutines_version = "1.3.2" + def coroutines_version = "1.3.8" def markwon_version = '4.1.2' def big_image_viewer_version = '1.6.2' def glide_version = '4.11.0' @@ -286,13 +286,13 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" - implementation "androidx.recyclerview:recyclerview:1.2.0-alpha04" - implementation 'androidx.appcompat:appcompat:1.1.0' + implementation "androidx.recyclerview:recyclerview:1.2.0-alpha05" + implementation 'androidx.appcompat:appcompat:1.2.0' implementation "androidx.fragment:fragment:$fragment_version" implementation "androidx.fragment:fragment-ktx:$fragment_version" // Keep at 2.0.0-beta4 at the moment, as updating is breaking some UI implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4' - implementation 'androidx.core:core-ktx:1.3.0' + implementation 'androidx.core:core-ktx:1.3.1' implementation "org.threeten:threetenbp:1.4.0:no-tzdb" implementation "com.gabrielittner.threetenbp:lazythreetenbp:0.7.0" @@ -390,9 +390,7 @@ dependencies { kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.0' // gplay flavor only - // Warning: due to the exclude, Android Studio does not propose to upgrade. Uncomment next line to be proposed to upgrade - // implementation 'com.google.firebase:firebase-messaging:20.0.0' - gplayImplementation('com.google.firebase:firebase-messaging:20.2.1') { + gplayImplementation('com.google.firebase:firebase-messaging:20.2.4') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index fbeb5b954d..6c406aa682 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -268,7 +268,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { Glide.get(requireContext()).clearMemory() session.fileService().clearCache() - var newSize = 0 + var newSize: Int withContext(Dispatchers.IO) { // On BG thread From bd238dcbfa7e09bb529ba5bc947585ae20829f50 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Aug 2020 22:24:29 +0200 Subject: [PATCH 004/257] Make user displayName live in the setting, it should fix #1926 --- CHANGES.md | 2 +- .../settings/VectorSettingsGeneralFragment.kt | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2f850c8a3c..ffd9a5f1af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Bugfix 🐛: - - + - Display name not shown under Settings/General (#1926) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index fbeb5b954d..e4120e8133 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -128,6 +128,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { super.onViewCreated(view, savedInstanceState) observeUserAvatar() + observeUserDisplayName() } private fun observeUserAvatar() { @@ -140,6 +141,21 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { .disposeOnDestroyView() } + private fun observeUserDisplayName() { + session.rx() + .liveUser(session.myUserId) + .unwrap() + .distinctUntilChanged { user -> user.displayName } + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { user -> + mDisplayNamePreference.let { + it.summary = user.displayName ?: "" + it.text = user.displayName ?: "" + } + } + .disposeOnDestroyView() + } + override fun bindPref() { // Avatar mUserAvatarPreference.let { @@ -151,8 +167,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { // Display name mDisplayNamePreference.let { - it.summary = session.getUser(session.myUserId)?.displayName ?: "" - it.text = it.summary.toString() it.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> newValue ?.let { value -> (value as? String)?.trim() } From eea17f0905eecde5bfc17bdefc723b46a62cf48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 21 Aug 2020 16:24:11 +0000 Subject: [PATCH 005/257] Translated using Weblate (Estonian) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/et/ --- vector/src/main/res/values-et/strings.xml | 329 +++++++++++++++++++++- 1 file changed, 327 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index b5dea7d957..fc3800682a 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -842,7 +842,7 @@ Avalik nimi (nähtav neile, kellega sa suhtled) Sessiooni avalik nimi on nähtav neile, kellega sa suhtled Avalik nimi - Seadme tunnus + Sessiooni tunnus Sessiooni võti Verifitseerimine Ed25519 sõrmejälg @@ -2200,4 +2200,329 @@ Saadab sõnumi vormindamata tekstina ega tõlgenda seda markdown-vormindusena - +Sul ei ole õigusi siin jututoas rühmakõne algatamiseks + Rühmakõne on hetkel käimas! + Alusta videokoosolekut + Alusta koosolekut + Koosolekud kasutavad Jitsi turvaloogikat ja õigusi. Kõik hetkel jututoas olijad näevad kutset koosolekuga liitumiseks. + Sa ei saa iseendale helistada + Sa ei saa iseendale helistada, palun oota ei teised osalejad kutsele vastaksid + Vidina lisamine ei õnnestunud + Vidina eemaldamine ei õnnestunud + + %1$d/%2$d võtme importimine õnnestus. + %1$d/%2$d võtme importimine õnnestus. + + + Halda lõiminguid + Aktiivseid vidinaid ei leidu + Jututuba on loodud, kuid mõned kutsed on saatmata järgmistel põhjustel: +\n +\n%s + + Ei õnnestunud dekrüptida ajajoonel leiduvat sõnumit + Sa parasjagu jagad oma e-posti aadressi ja telefoninumbrit isikutuvastusserveriga %1$s. Selleks, et lõpetada see jagamine, pead uuesti looma ühenduse isikutuvastusserveriga %2$s. + Detailne logimine võimaldab arendajatel saada rohkem teadet kui sa peale nutiseadme tõsist raputamist saadad veateate. Kui ka detailne logimine on kasutusel, siis rakendus ei logi sõnumite sisu ega isiklikke andmeid. + + + Kui sa oled nõustunud koduserveri kasutustingimustega, siis palun proovi uuesti. + + Tundub, et server ei suuda päringule mõistliku ajaga vastata ning see võib olla seotud kas vigase ühendusega või serveri veaga. Palun proovi mõne aja pärast uuesti. + + Ava navigatsioonivalik + Ava menüüvalik jututoa loomiseks + Sulge menüüvalik jututoa loomiseks… + Sulge võtmete varunduse teade + Näita salasõna + Peida salasõna + Mine lõppu + + + %1$s, %2$s ja %3$d muu loevad + %1$s, %2$s ja %3$d muud loevad + + %1$s, %2$s ja %3$s lugesid + %1$s ja %2$s lugesid + %s luges + + 1 kasutaja luges + %d kasutajat lugesid + + + See fail „%1$s“ (%2$s) on üleslaadimiseks liiga suur. Failisuuruse ülempiir on %3$s. + + Manuse laadimisel tekkis viga. + Fail + Kontakt + Kaamera + Heli + Meediagalerii + Kleeps + Jagatud andmete töötlemine ei õnnestunud + + MEEDIA + EIRA KASUTAJAT + + Teatasin sisust + Selle sisu kohta on nüüd teade saadetud. +\n +\nKui sa ei soovi enam näha selle kasutaja sisu, siis sa võid tema sõnumite peitmiseks kasutaja blokeerida + See on rämpssõnum + Haldaja sai nüüd teate, et see sisu on rämpssõnum. +\n +\nKui sa ei soovi enam näha selle kasutaja sisu, siis sa võid tema sõnumite peitmiseks kasutaja blokeerida + See sõnum ei ole sobilik + Haldaja sai nüüd teate, et see sisu ei ole sobilik. +\n +\nKui sa ei soovi enam näha selle kasutaja sisu, siis sa võid tema sõnumite peitmiseks kasutaja blokeerida + + Läbiva krüptograafia jaoks vajalike võtmete salvestamiseks kohalikule andmekandjale vaajab Element sinu luba. +\n +\nSelleks et saaksid võtmed käsitsi eksportida, siis palun anna selleks järgmises vaates luba. + + Hetkel puudub võrguühendus + + Eira kasutajat + + Kõik sõnumid (lärmakas) + Kõik sõnumid + Ainult mainimised + Summuta + Seadistused + Lisa lemmikuks + Eemalda lemmikute hulgast + Lahku sellest jututoast + %1$s ei teinud muudatusi + Sina ei teinud muudatusi + Saadab selle sõnumi rõõmurikkujana + Rõõmurikkuja + Reageerimiste leidmiseks sisesta otsingusõnad. + + See on sinu vestlus, mida sa ka tegelikult kontrollid. + Salasõna kinnitamiseks klõpsi kirjas olnud linki. Kui oled avanud selles kirjas leidunud lingi, siis palun vajuta järgnevat nuppu. + Kui sul juba on kasutajakonto ning sa tead oma Matrix\'i kasutajatunnust ja salasõna, siis alternatiivina sa võid kasutada seda meetodit: + Logi sisse Matrix\'i kasutajatunnusega + Logi sisse oma Matrix\'i kasutajatunnusega + Kui sa võtad kasutusele konto koduserveris, siis sisesta alljärgnevalt oma Matrix\'i kasutajatunnus (näiteks @torekasutaja:domeen.ee) ja salasõna. + Matrix\'i kasutajatunnus + Kui sa ei tea oma salasṍna, siis mine tagasi ja loo uus salasõna. + Nähtud kasutaja poolt + + Sa oled loginud välja + See võib juhtuda eri põhjustel: +\n +\n• Sa oled muutnud oma salasõna mõnes teises sessioonis. +\n +\n• Sa oled selle sessiooni kustutanud mõnest teisest sessioonist. +\n +\n• Sinu koduserveri haldaja on turvakaalutlustel keelanud sinu ligipääsu. + Logi uuesti sisse + + Sa oled loginud välja + Praegune sessioon kuulub kasutajale %1$s, kuid sina üritad siseneda kasutaajaga %2$s. Sellist võimalust Element hetkel ei toeta. +\nPalun eemalda kõik andmed ning siis logi sisse muu kontoga. + + Mõni järgnevatest võib olla sattunud valedesse kätesse: +\n +\n - Sinu koduserver +\n - Selle osapoole koduserver, keda sa üritad verifitseerida +\n - Sinu või teise osapoole internetiühendus +\n - Sinu või teise osapoole seade + + Video. + Pilt. + Helifail + Fail + Lisaturvalisus mõttes verifitseeri see kasutaja võrreldes selleks üheks korraks loodud koodi mõlemas seadmes. +\n +\nLisaturvalisuse mõttes tehke seda omavahel kohtudes. + Sõnumid siin jututoas on läbivalt krüptitud. + Sõnumid siis jututoas kasutavad läbivat krüptimist. +\n +\nSinu sõnumid on turvatud ning ainult sinul ja saaja(te)l on unikaalsed võtmed selliste sõnumite lugemiseks. + Turvalisus + Lisateave + Veel + Haldustegevused + Jututubade seadistused + Teavitused + + Üks inimene + %1$d inimest + + Üleslaetud failid + Lahku jututoast + Lahkun jututoast… + + Haldajad + Moderaatorid + Kohandatud õigused + Kutsed + Kasutajad + + Peakasutaja jututoas %1$s + Moderaator jututoas %1$s + Vaikimisi õigused jututoas %1$s + Kohandatud õigused (%1$s) jututoas %2$s + + Hüppa lugemisteatise juurde + + Element ei oska käsitleda %1$s-tüüpi sündmusi + Element ei oska käsitleda %1$s-tüüpi sünumeid + Tekkis viga, kui Element üritas töödelda sõnumi %1$s sisu + + Lõpeta eiramine + + See sessioon ei oska jagada verifitseerimisteavet sinu teiste sessioonidega. +\nSeni salvestatakse verifitseerimisteave kohalikus seadmes ja jagatakse rakenduse tulevases versioonis. + + Hiljutised jututoad + Kuni antud kasutaja seda sessiooni ei usalda, on ta märgitud hoiatussildiga. Alternatiivina on sul võimalus verifiseerimist ka käsitsi teha. + + + Käivita risttunnustamine + Lähtesta krüptovõtmed + + QR-kood + + Peaaegu valmis! Kas %s kuvab sama kilpi\? + Jah + Ei + + Ühendus sinu serveriga on katkenud + Lennurežiim on kasutusel + + Arendaja töövahendid + Kasutajakonto andmed + + %d hääl + %d häält + + + %d hääl - lõplikud tulemused + %d häält - lõplikud tulemused + + Tehtud valik + Loob lihtsa hääletuse + Kasuta taastamiseks mõeldud paroolifraasi või võtit + Kui sa ei pääse ligi olemasolevale sessioonile + + Uus sisselogimine + + Ei leia turvahoidlast vajalikke andmeid + Sisesta turvahoidla paroolifraas + Hoiatus: + Sa peaksid turvahoidlat kasutama vaid usaldusväärsest seadmest + + Eemalda… + Kas sa soovid seda manust saata kasutajale %1$s\? + + Saada pilt algupärases suuruses + Saada pildid algupärases suuruses + + + Kinnita eemaldamine + Kas sa oled kindel et soovid eemaldada (kustutada) seda sündmust\? Pane tähele, et see muutus võib tagasi pöörduda, kui muudad hiljem jututoa nime või teema nime. + Lisa põhjus + Kustutamise põhjus + + Kasutaja kustutas sündmuse, põhjusena %1$s + Jututoa haldur on sündmust modereerinud, põhjusena %1$s + + Krüptovõtmed on juba uuendatud! + + Element Android + + Päringud võtmete laadimiseks + + Võta krüptitud sõnumite ajalugu lukust lahti + + Värskenda + + Uus sisselogimine. Kas see olid sina\? + Kontrollimiseks ja verifitseerimiseks klõpsi + Kui sa katkestad, siis sa ei saa selles seadmes lugeda krüptitud sõnumeid ning muud kasutajad ei usalda seda + Kui sa katkestad, siis sa ei saa oma uues seadmes lugeda krüptitud sõnumeid ning muud kasutajad ei usalda seda + Kui sa nüüd katkestad, siis sa ei verifitseeri seadet %1$s (%2$s). Alusta uuesti sealsest profiilist. + + Mõni järgnevatest võib olla sattunud valedesse kätesse: +\n +\n - Sinu salasõna +\n - Sinu koduserver +\n - Sinu või teise osapoole seade +\n - Sinu või teise osapoole internetiühendus +\n +\nPalun vaheta seadistuste lehelt koheselt oma kasutajakonto salasõna ja taastevõti. + + Seadistuste lehelt verifitseeri oma seade. + Verifitseerimine on tühistatud + + Taastamiseks mõeldud paroolifraas + Sõnumite krüptovõti + Kasutajakonto salasõna + + Seadista %s + Loo sõnumite krüptovõti + + Kinnita %s + + Sinu %2$s ja %1$s on seadistatud. +\n +\nHoia neid turvaliselt! Kui sa oled oma rakendustes kõik sessioonid sulgenud, siis sa vajad neid ligipääsu taastamiseks oma krüptitud sõnumitele ja turvalistele andmetele. + + Vigane salasõna ja/või kasutajanimi. Palun vaata, kas mitte sisestatud salasõna ei alga või lõppe tühikutega. + See kasutajakonto on deaktiveeritud. + + Sõnum… + + Krüptimise uuendus on saadaval + Võta risttunnustamine kasutusele + Selleks et sinu vestlused oleks turvatud, verifitseeri end ja teisi + + Jätkamaks sisesta oma %s + Kasuta faili + + Sisesta %s + Taastamiseks mõeldud paroolifraas + See ei ole sobilik taastevõti + Palun sisesta taastevõti + + Kontrollin varukoopia võtmeid + Kontrollin varukoopia võtit (%s) + Arvutan elliptilise joone võtit + Loon paroolifraasi alusel SSSS\'i + Loon paroolifraasi alusel SSSS\'i (%s) + Loon taastevõtme alusel SSSS\'i + Salvestan võtmete varunduse andmed SSSS\'is + %1$s (%2$s) + + Jätkamiseks sisesta oma võtmete varunduse paroolifraas. + või kasuta oma võtmete varukoopia taastevõtit + Kui sa ei tea oma võtmete varunduse paroolifraasi, siis sa võid %s. + Võtmete varukoopia taastevõti + + Ära luba sel rakendusel teha ekraanitõmmiseid + Selle seadistusega määratakse FLAG_SECURE märge kõikidele tegevustele. Muutuse jõustamiseks vajab rakendus uuesti käivitamist. + + Lisasime meediafaili galeriisse + Meediafaili galeriisse lisamine ei õnnestunud + Meediafaili salvestamine ei õnnestunud + Määra kontole uus salasõna… + + Kasuta kõige uuemat Element\'i versioon mõnes muus seadmes, nagu näiteks Element Web, Element Desktop, Element iOS, Element Android. Samuti sobib mõni muu Matrix\'i klient, mis oskab risttunnustamist + Element Web +\nElement Desktop + Element iOS +\nElement Android + või mõnda teist Matrix\'i klienti, mis oskab risttunnustamist + Kasuta oma muus seadmes kõige uuemat Element\'i versiooni: + Sunnib loobuma praeguse krüptitud jututoa rühmavestluse seansist + Funktsionaalsus on toetatud ainult krüptitud jututubades + Jätkamiseks kasuta kas oma %1$s või %2$s. + + Vale PIN-kood, jäänud on %d katse + Vale PIN-kood, jäänud on %d katset + + Hoiatus! Viimane katse enne väljalogimist! + Liiga palju vigu PIN-koodi sisestamisel ning sa oled nüüd välja logitud + From 6ad0098767fbef0f92b9a8271ce0687ceb554554 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 21 Aug 2020 17:40:20 +0000 Subject: [PATCH 006/257] Translated using Weblate (Bulgarian) Currently translated at 75.4% (1394 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/bg/ --- vector/src/main/res/values-bg/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-bg/strings.xml b/vector/src/main/res/values-bg/strings.xml index 30689751d6..da7b92fdd3 100644 --- a/vector/src/main/res/values-bg/strings.xml +++ b/vector/src/main/res/values-bg/strings.xml @@ -1926,4 +1926,6 @@ Съобщението беше изтрито Показвай премахнатите съобщения Показвай индикатор на мястото на премахнатите съобщения - +Възпроизведи + Пауза + From 16809a53ab6ac5e62ba475069fdb31ddc72fc84a Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Sat, 22 Aug 2020 03:49:03 +0000 Subject: [PATCH 007/257] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/zh_Hant/ --- vector/src/main/res/values-zh-rTW/strings.xml | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index fbf26817b8..000bfd6a46 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -698,7 +698,7 @@ 發送者的工作階段訊息 公開名稱 公開名稱 - ID + 工作階段 ID 工作階段金鑰 驗證 Ed25519 指紋 @@ -1630,7 +1630,7 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 回報此內容 回報此內容的理由 回報 - 封鎖使用者 + 忽略使用者 內容已回報 此內容已回報。 @@ -1689,7 +1689,7 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 讀取 DRM 保護的媒體 這不是有效的 Matrix 伺服器位置 - 封鎖使用者 + 忽略使用者 所有訊息(吵雜) 所有訊息 @@ -2516,4 +2516,31 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意 確認 PIN 碼以停用 PIN 碼 避免意外的通話 開始通話前要求確認 - +您沒有在此聊天室中開始會議通話的權限 + 會議已在進行中! + 開始視訊會議 + 開始音訊會議 + 會議使用 Jitsi 安全與權限策略。目前在聊天室中的所有人在您的會議開始時都會看到加入的邀請。 + 您無法與自己通話 + 您無法與自己進行通話,請等候參與者接受邀請 + 新增小工具失敗 + 移除小工具失敗 + + %1$d/%2$d 金鑰匯入成功。 + + + 管理整合 + 無作用中的小工具 + 已建立聊天室,但因為以下理由而未傳送某些邀請: +\n +\n%s + + + %1$s, %2$s 與 %3$d 個其他人已讀取 + + + 錯誤的代碼,還可以嘗試 %d 次 + + 警告!登出前的最後一次嘗試! + 太多錯誤,您已被登出 + From 471497e7213a7f27971f8c04f617db25bc3afbc1 Mon Sep 17 00:00:00 2001 From: aWeinzierl Date: Sat, 22 Aug 2020 15:32:44 +0000 Subject: [PATCH 008/257] Translated using Weblate (German) Currently translated at 99.7% (1843 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 24 +++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 2579effd9c..3ece35d4f8 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -608,7 +608,7 @@ Beachte: Diese Aktion wird die App neu starten und einige Zeit brauchen.Informationen der Absendersitzung Öffentlicher Name Öffentlicher Name - ID + Sitzungs-ID Sitzungsschlüssel Verifizierungsstatus Ed25519-Fingerabdruck @@ -2624,4 +2624,24 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Verhindern Sie versehentliche Anrufe Bitten Sie um Bestätigung, bevor Sie einen Anruf tätigen Konfiguration - +Dir fehlt die Berechtigung in diesem Raum eine Konferenz zu starten + Es ist bereits eine Konferenz aktiv! + Starte eine Videokonferenz + Starte eine Audiokonferenz + Konferenzen nutzen die Jitsi Sicherheits- und Berechtigungsrichtlinien. Alle im Raum Anwessenden können während der Konferenz beitreten. + Du kannst dich nicht selbst anrufen + Du kannst dich nicht selbst anrufen, warte bis Teilnehmer die Einladung annehmen + Hinzufügen des Widgets fehlgeschlagen + Entfernen des Widgets fehlgeschlagen + + %1$d/%2$d Schlüssel erfolgreich importiert. + %1$d/%2$d Schlüssel erfolgreich importiert. + + + Verwalte Integrationen + Keine aktiven Widgets + Der Raum wurde erstellt, aber manche Einladungen wurden aus folgendem Grund nicht versendet: +\n +\n%s + + From 4380d34645612e5d1a712e8ecd1179b6514a761d Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Fri, 21 Aug 2020 14:56:47 +0000 Subject: [PATCH 009/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3 of 3 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.riot.im/projects/element-android/element-store/pt_BR/ --- .../main/play/listings/pt_BR/full_description.txt | 12 ++++++------ .../main/play/listings/pt_BR/short_description.txt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/play/listings/pt_BR/full_description.txt b/vector/src/main/play/listings/pt_BR/full_description.txt index a3b5dda311..82b38b473c 100644 --- a/vector/src/main/play/listings/pt_BR/full_description.txt +++ b/vector/src/main/play/listings/pt_BR/full_description.txt @@ -3,7 +3,7 @@ Element é um novo tipo de aplicativo de mensagens e colaboração que: 1. Coloca você no controle de sua privacidade; 2. Permite que você se comunique com qualquer pessoa na rede Matrix e, através de integrações, outros aplicativos como o Slack; 3. Protege você de anúncios, mineração de dados e de ecossistemas fechados; -4. Faz uso da criptografia de ponta-a-ponta, com assinatura cruzada para verificar outros. +4. Faz uso da criptografia de ponta a ponta, com autoverificação para confirmar outras pessoas. Element é completamente diferente de outros aplicativos de mensagem e colaboração porque é descentralizado e código aberto. @@ -19,12 +19,12 @@ Element coloca você no controle ao permitir quem hospeda suas conversas. Neste Por que escolher o Element? -SEJA O DONO DE SEUS DADOS: Você decide onde manter seus dados e mensagens. Você é o dono deles e também os controla, não alguma mega corporação que minera os seus dados ou compartilha eles com terceiros. +SEJA O DONO DE SEUS DADOS: você decide onde manter seus dados e mensagens. Você é o dono deles e também os controla, não alguma mega corporação que minera os seus dados ou compartilha eles com terceiros. -COLABORAÇÃO E MENSAGENS ABERTAS: Você pode falar com qualquer outra pessoa na rede Matrix, não importa se ela está usando o Element ou algum outro aplicativo Matrix, ou até mesmo se ela está utilizando um sistema de mensagens diferente como o Slack, IRC ou XMPP. +COLABORAÇÃO E MENSAGENS ABERTAS: você pode falar com qualquer outra pessoa na rede Matrix, não importa se ela está usando o Element ou algum outro aplicativo Matrix, ou até mesmo se ela está utilizando um sistema de mensagens diferente como o Slack, IRC ou XMPP. -SUPER-SEGURO: Criptografia de ponta-a-ponta verdadeira (apenas aqueles na conversa podem descriptografar mensagens), e assinatura cruzada para verificar os dispositivos de participantes de conversas. +SUPER-SEGURO: criptografia de ponta a ponta verdadeira (apenas aqueles na conversa podem descriptografar mensagens), e assinatura cruzada para verificar os dispositivos de participantes de conversas. -COMUNICAÇÃO COMPLETA: Mensagens, chamadas de voz, chamadas de vídeo, compartilhamento de arquivos, compartilhamento de tela e um monte de integrações, robôs e widgets. Construa salas, comunidades, mantenha contato e faça seus projetos. +COMUNICAÇÃO COMPLETA: mensagens, chamadas de voz, chamadas de vídeo, compartilhamento de arquivos, compartilhamento de tela e um monte de integrações, robôs e widgets. Construa salas, comunidades, mantenha contato e faça seus projetos. -NÃO IMPORTA ONDE VOCÊ ESTEJA: Mantenha contato não importa onde você esteja com o histórico sincronizado de mensagens em todos os seus dispositivos e no navegador em https://app.element.io. +NÃO IMPORTA ONDE VOCÊ ESTEJA: mantenha contato não importa onde você esteja com o histórico sincronizado de mensagens em todos os seus dispositivos e no navegador em https://app.element.io. diff --git a/vector/src/main/play/listings/pt_BR/short_description.txt b/vector/src/main/play/listings/pt_BR/short_description.txt index 7dd54cd2fd..853f629c30 100644 --- a/vector/src/main/play/listings/pt_BR/short_description.txt +++ b/vector/src/main/play/listings/pt_BR/short_description.txt @@ -1 +1 @@ -Bate-papo seguro descentralizado e voz sobre IP. Mantenha seus dados seguros. +Conversas e chamadas seguras e descentralizadas. Mantenha seus dados protegidos. From 370d57cfbc8434b76bb317e7a83ca11d5778c15f Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Sat, 22 Aug 2020 12:57:49 +0000 Subject: [PATCH 010/257] Translated using Weblate (Russian) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/ru/ --- vector/src/main/res/values-ru/strings.xml | 73 ++++++++++++++++------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 72291bdb04..11b758578c 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 пользователей - + Отправить логи @@ -611,7 +611,7 @@ Информация о сессии отправителя Публичное имя Публичное имя - ID + ID сессии Ключ сессии Проверка Ed25519 отпечаток @@ -832,13 +832,13 @@ %d комната %d комнаты %d комнат - + %d комната %d комнаты %d комнат - + %1$s в %2$s @@ -846,7 +846,7 @@ %d активный виджет %d активных виджета %d активных виджетов - + @@ -856,45 +856,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 непрочитанных уведомлений - + Получить аватар Заметка аватара @@ -1029,20 +1029,20 @@ %d выбран %d выбрано %d выбраны - + %d участник %d участника %d участников - + %d комната %d комнаты %d комнат - + Системные оповещения @@ -1303,7 +1303,7 @@ %d новый ключ был добавлен к этому устройству. %d новых ключа были добавлены к этому устройству. %d новых ключей были добавлены к этому устройству. - + @@ -1354,7 +1354,7 @@ Резервное копирование %d ключа… Резервное копирование %d ключей… Резервное копирование %d ключей… - + Все ключи сохранены @@ -1774,7 +1774,7 @@ Звук Галерея Это спам - Заблокировать пользователя + Игнорировать пользователя Все сообщения Только при упоминаниях @@ -1792,7 +1792,7 @@ Стикер Причина жалобы на контент Пожаловаться - Заблокировать пользователя + ИГНОРИРОВАТЬ ПОЛЬЗОВАТЕЛЯ Все сообщения (громко) Без звука @@ -2664,4 +2664,37 @@ Подтвердите PIN-код, чтобы отключить PIN-код Предотвращение случайных звонков Спрашивать подтверждение перед звонком - +У вас нет разрешения на запуск конференции в этой комнате + Конференция уже идет! + Начать видеовстречу + Начать аудиовстречу + На встречах используются политики безопасности и разрешения Jitsi. Все люди, находящиеся в данный момент в комнате, увидят приглашение присоединиться во время вашей встречи. + Вы не можете позвонить самому себе + Вы не можете позвонить самому себе, дождитесь, пока участники примут приглашение + Не удалось добавить виджет + Не удалось удалить виджет + + %1$d/%2$d ключ успешно импортирован. + %1$d/%2$d ключа успешно импортированы. + %1$d/%2$d ключей успешно импортировано. + + + Управление интеграциями + Нет активных виджетов + Комната создана, но некоторые приглашения не отправлены по следующей причине: +\n +\n%s + + + %1$s, %2$s и %3$d читает + %1$s, %2$s и %3$d других читают + %1$s, %2$s и %3$d других читают + + + Неверный код, осталась %d попытка + Неверный код, осталось %d попытки + Неверный код, осталось %d попыток + + Предупреждение! Последняя оставшаяся попытка перед выходом из системы! + Слишком много ошибок, вы вышли из системы + From c73f544a0187bb94adf6b56776f6e8449af2b2c7 Mon Sep 17 00:00:00 2001 From: AnonymousWebHacker Date: Fri, 21 Aug 2020 18:11:34 +0000 Subject: [PATCH 011/257] Translated using Weblate (Spanish) Currently translated at 81.6% (1508 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/es/ --- vector/src/main/res/values-es/strings.xml | 217 +++++++++++++++++++++- 1 file changed, 215 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 84ea53d685..449d7e0bc7 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -40,7 +40,7 @@ Debido a que faltan permisos, pueden faltar algunas características… Necesitas permiso para invitar a iniciar una conferencia en esta sala No se puede iniciar la llamada - Información de la sesión + Detalles de la sesión No se admiten llamadas de conferencia en salas cifradas Enviar de Todos Modos o @@ -1916,4 +1916,217 @@ La visibilidad de mensajes en Matrix es similar a la del correo electrónico. Qu Buscar en mis contactos Rechazar invitación Confirma PIN para desabilitarlo - +No posee permisos para iniciar una conferencia en esta sala + Conferencia en progreso! + Iniciar Video Conferencia + Iniciar Audio Conferencia + No puedes hacer una llamada contigo mismo + No puedes hacer una llamada contigo mismo, espera a que los participantes acepten la invitación + Fallo al adicionar Widget + Fallo al eliminar Widget + Prevenir llamadas por accidente + Pedir confirmacion antes de iniciar una llamda + Rason de expulsion + Banear usuario + Rason de baneo + Desbanear usuario + Desbanear usuario y permitir entrar a la sala nuevamente. + + nombre_session: + Error al descifrar el mensaje en la línea de tiempo + Adicionar pestaña dedicada para notificaciones no leidas en la pantalla principal. + + Descripcion muy corta + + Sincronización inicial… + + Mostrar todas mis sessiones + Opciones Avanzadas + Modo Desarrollador + Agitar + Sensibilidad + Agite su dispositivo para probar la sensibilidad + Sacudida detectada! + Ajustes + Sesión Actual + Otras Sesiones + + Mostrando solo el primer resultado, agregue mas letras… + + Fallar rapido (Test) + Element puede fallar con más frecuencia cuando ocurre un error inesperado + + Antepone ¯\\_(ツ)_/¯ a un mensaje de texto sin formato + + Habilitar encriptacion + Una vez habilitada, el cifrado no se puede deshabilitar. + + Su dominio de correo electrónico no está autorizado para registrarse en este servidor + + Inicio de sesión no confiable + Coinciden + No coinciden + Verifique a este usuario confirmando que el siguiente emoji único aparece en su pantalla, en el mismo orden. + Para mayor seguridad, use otro medio de comunicación confiable o hágalo en persona. + Busque el escudo verde para asegurarse de que se confía en un usuario. Confíe en todos los usuarios de una sala para asegurarse de que la sala sea segura. + + No seguro + Video. + Imagen. + Audio + Archivo + Sticker + + Esperando… + %s cancelada + Cancelado por usted + %s aceptada + Aceptado por usted + Verificacion enviada + Solicitud de verificación + Verifica esta Sesion + Verificar manualmente + + Usted + + Escanee el código con el dispositivo del otro usuario para verificarse mutuamente de forma segura + Escanear código + Error al escanear + Si no estás en persona, compara los emojis + + Verificar comparando emojis + + Verificar por emojis + Si no puede escanear el código anterior, verifique comparando una selección breve y única de emoji. + + Imagen de código QR + + Verificar %s + Verificado %s + Esperando por %s… + Los mensages en esta sala no estan encriptados punto a punto. + Seguridad + Saber mas + Mas + Acciones Administrativas + Ajustes de Sala + Notificaciones + + Una persona + %1$d personas + + Archivos, Medias y Documentos + Abandonar Sala + Saliendo de la sala… + + Administradores + Moderadores + Nivel Personalizado + Invitados + Usuarios + + Administrador en %1$s + Moderador en %1$s + Nivel Personalizado en %1$s + Nivel Personalizado (%1$d) en %2$s + + Saltar para leer el recibo + + Element no maneja eventos de tipo \'%1$s\' + Element no maneja el mensaje de tipo \'%1$s\' + Element encontró un problema al representar el contenido del evento con el ID \'%1$s\' + + Dejar de ignorar + + Salas recientes + Otras salas + + Envía el mensaje dado en colores + Linea de tiempo + + Editor de mensage + + Encriptar (end-to-end) + Una vez habilitado, el cifrado no se puede deshabilitar. + + Encriptar \? + Habilitar el cifrado + + Firma cruzada + Firma cruzada no habilitada + + Sesiones Activas + Mostrar todas las Sesiones + Administrar Sesiones + Cerrar Sesión + + Verificar este inicio de sesión + Otros usuarios pueden no confiar en la sesion + Completar Seguridad + + Verificar + Verificada + Precaucion + + Error al obtener sesiones + Sesiones + Confirmado + No es confiable + + Inicializar Firmas Cruzadas + Restablecer claves + + Codigo QR + + Correcto + No + + Sin conexión + Modo Avion Activado + + Herramientas de desarrollo + Datos de cuenta + Seleccionar Opcion + Nuevo inicio de sesión + + Advertencia: + Remover… + Razón + Razón para redactar + + Element Android + + Refrescar + + Nuevo inicio de sesión detectado . ¿Fue usted\? + Toca para revisar y verificar + Este no era yo + Su cuenta puede estar comprometida + + Verificación cancelada + + Frase de contraseña de recuperación + Clave de mensaje + Contraseña de la cuenta + + ¡Listo! + Cifrado habilitado + Sala creada y configurada por usted. + + Esperando por %s… + + Ajuste de Notificaciones + Mensaje… + + Introduza su %s para continuar + Usar archivo + + No se pudo guardar el archivo multimedia + Verificar Sesión + Confirmar PIN + Resetear PIN + Nuevo PIN + Para resetear su PIN, debe iniciar seccion y crear uno nuevo + Establecer PIN + Si decea resetear su PIN, toque Olvidé PIN para cerrar sesión y restablecer. + From 7ee4a8fc0a62882d6a760c72543833aafc1b58ee Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 22 Aug 2020 11:53:20 +0000 Subject: [PATCH 012/257] Translated using Weblate (Swedish) Currently translated at 61.0% (1127 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 485 +++++++++++++++++++++- 1 file changed, 466 insertions(+), 19 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index f1ffb2079a..9fef0aa6b6 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -24,7 +24,7 @@ Gemenskapsdetaljer Skicka ett klistermärke Säkerhetskopiering av nycklar - Använd säkerhetskopiering av nycklar + Använd nyckelsäkerhetskopiering Verifiera session Säkerhetskopiering av nycklar är inte färdig, vänligen vänta… @@ -33,7 +33,7 @@ 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 + Använd nyckelsäkerhetskopiering Ä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. @@ -341,21 +341,21 @@ Kan inte spela in video Information - Element behöver tillstånd att komma åt ditt foto- och videobibliotek för att skicka och spara bilagor. -\n -\nVänligen tillåt åtkomst i nästa pop-up för att kunna skicka filer från din telefon. + Element behöver tillstånd att komma åt ditt foto- och videobibliotek för att skicka och spara bilagor. +\n +\nVänligen ge tillstånd i nästa popup för att kunna skicka filer från din telefon. Element behöver tillstånd att komma åt din kamera för att kunna ta bilder och hålla videosamtal. " \n -\nVänligen ge tillgång i nästa pop-up för att kunna utföra samtalet." +\nVänligen ge tillstånd i nästa popup för att kunna utföra samtalet." Element behöver tillstånd att komma åt din mikrofon för hålla röstsamtal. " \n -\nVänligen ge tillgång i nästa pop-up för att kunna utföra samtalet." - Element behöver tillstånd att komma åt din kamera och mikrofon för att kunna utföra videosamtal. -\n -\nVänligen ge tillgång i nästa pop-up för att kunna utföra samtalet. - Element kan kolla i din adressbok för att hitta andra Matrixanvändare baserat på deras e-postadresser och telefonnummer. Om du går med på att dela din adressbok för detta ändamål, vänligen ge tillgång i nästa pop-up. +\nVänligen ge tillstånd i nästa popup för att kunna utföra samtalet." + Element behöver tillstånd att komma åt din kamera och mikrofon för att kunna utföra videosamtal. +\n +\nVänligen ge tillstånd i nästa popup för att kunna utföra samtalet. + Element kan kolla i din adressbok för att hitta andra Matrixanvändare baserat på deras e-postadresser och telefonnummer. Om du går med på att dela din adressbok för detta ändamål, vänligen ge tillstånd i nästa popup. Element kan kolla i din adressbok för att hitta andra Matrixanvändare baserat på deras e-postadresser och telefonnummer. \n \nVill du dela din adressbok för detta ändamål\? @@ -439,7 +439,7 @@ Återställ till vanlig användare Gör till moderator Gör till administratör - Dölj alla meddelanden från den här användaren + Ignorera Filtrera rumsmedlemmar RUM RUM @@ -742,7 +742,7 @@ Ogiltigt hemserversvar Du har blivit utloggad på grund av ogiltiga eller utgångna uppgifter. - Verifiera den här sessionen för att markera den som pålitligt. Att lita på folks sessioner ger dig extra sinnesro när du skickar totalsträckskrypterade meddelanden. + Verifiera den här sessionen för att markera den som betrodd. Att lita på folks sessioner ger dig extra sinnesro när du skickar totalsträckskrypterade meddelanden. Säkra meddelanden mellan dig och den här användaren är totalsträckskrypterade och kommer inte att vara läsbara för tredje parter. Du använder ingen identitetsserver @@ -774,7 +774,7 @@ Du delar för närvarande e-postadresser och telefonnummer på hemservern %1$s. Du kommer behöva återansluta till %2$s för att sluta dela dem. Acceptera identitetsserverns (%s) användarvillkor för att låta dig själv vara upptäckbar med e-postadress eller telefonnummer. - Mångord loggar kommer att hjälpa utvecklare genom att skicka mer loggar när du skickar en raseriskakning. Även när det är aktiverat, så loggar appen inga meddelandeinnehåll eller annan privat data. + Mångordiga loggar kommer att hjälpa utvecklare genom att skicka mer loggar när du skickar en raseriskakning. Även när det är aktiverat, så loggar appen inga meddelandeinnehåll eller annan privat data. Visa lösenord @@ -869,10 +869,10 @@ Efter aktivering så kan kryptering inte avaktiveras. Meddelanden som skickas i ett krypterat rum kan inte läsas av servern, bara av deltagarna i rummet. Att aktivera kryptering kan kan göra att många bottar och bryggor inte funkar ordentligt. Meddelanden mellan dig och den här användaren är totalsträckskrypterade och kan inte läsas av tredje parter. - Din nya session är nu verifierad. Den har tillgång till dina krypterade meddelanden, och andra användare kommer att se den som pålitlig. + Din nya session är nu verifierad. Den har tillgång till dina krypterade meddelanden, och andra användare kommer att se den som betrodd. - Verifiera den här sessionen gör att markera den som pålitlig och ge den tillgång till dina krypterade meddelanden. Om det inte var du som loggade in i den här sessionen så kan ditt konto vara kapat: + Verifiera den här sessionen gör att markera den som betrodd och ge den tillgång till dina krypterade meddelanden. Om det inte var du som loggade in i den här sessionen så kan ditt konto vara kapat: Använd en existerande session för att verifiera den här och ge den tillgång till krypterade meddelanden. @@ -956,7 +956,7 @@ %d nya meddelanden - Certifikatet har ändrats från en pålitligt till en som vi inte litar på. Servern kan ha förnyat sitt certifikat. Kontakta serveradministratören för det förväntade fingeravtrycket. + Certifikatet har ändrats från ett betrott till ett som inte är betrott. Servern kan ha förnyat sitt certifikat. Kontakta serveradministratören för det förväntade fingeravtrycket. Inställningar Inställningar Systeminställningar. @@ -1101,8 +1101,455 @@ Väntar på det här meddelandet, det här kan ta ett tag Vid totalsträckskryptering så kan du behöva vänta på att någons meddelande ska komma för att krypteringsnycklarna inte har skickats till dig. Du kan inte komma åt det här meddelandet för att du har blockerats av avsändaren - Du kan inte komma åt det här meddelandet för att avsändaren inte litar på din session + Du kan inte komma åt det här meddelandet för att din session inte är betrodd av avsändaren Du kan inte komma åt det här meddelandet för att avsändaren avsiktligt inte skickade nycklarna Sök i mina kontakter Din kontaktbok är tom - +Du har inte behörighet att starta ett gruppsamtal i det här rummet + Ett gruppsamtal pågår redan! + Starta videomöte + Starta ljudmöte + Möten använder Jitsis säkerhets- och behörighetsprinciper. Alla personer nu i rummet kommer att se en inbjudan för att gå med medans mötet pågår. + Du kan inte ringa ett samtal till dig själv + Du kan inte ringa ett samtal till dig själv, vänta tills deltagare accepterar inbjudan + Misslyckades att lägga till widget + Misslyckades att ta bort widget + Elementsamtal misslyckades + Misslyckades att upprätta en realtidsuppkoppling. +\nVänligen be administratören för din hemserver att konfigurera en TURN-server för att samtal ska fungera pålitligt. + + Välj ljudenhet + Telefon + Högtalare + Hörlurar + Trådlösa hörlurar + Fram + Bak + Stäng av HD + Sätt på HD + + SSL-fel: andra partens identitet har inte verifierats. + SSL-fel. + Förhindra oavsiktligt samtal + Fråga efter bekräftelse innan ett samtal startas + Aktivt samtal (%s) + Återgå till samtal + + Avbryt inbjudan + Omnämn + Visa sessionslista + Du kommer inte kunna ångra den här ändringen eftersom du befordrar användaren till samma användarnivå som dig själv. +\nÄr du säker\? + + Degradera dig själv\? + Du kommer inte kunna ångra den här ändringen eftersom du degraderar dig själv. Om du är den sista privilegierade användaren i det här rummet så kommer det att vara omöjligt att återfå privilegier. + Degradera + + + Ignorera användare + Avignorera användare + Att avignorera den här användaren kommer att visa alla meddelanden från hen igen. + Avbryt inbjudan + Är du säker på att du vill avbryta inbjudan för den här användaren\? + Sparka ut användaren + Anledning för utsparkning + att sparka ut användaren kommer att ta bort hen från det här rummet. +\n +\nFör att hindra hen från att gå med i rummet igen så bör du banna hen istället. + Banna användaren + Anledning för bann + Avbanna användaren + Att banna användaren kommer att sparka ut hen från det här rummet och hindra hen från att gå med igen. + Att avbanna användaren kommer att låta hen gå med i rummet igen. + + Anledning + + "%1$s, " + %1$s och %2$s + %1$s %2$s + + LOKALA KONTAKTER (%d) + ANVÄNDARKATALOG (%s) + Endast Matrixanvändare + + Sök + %s skriver… + %1$s och %2$s skriver… + %1$s, %2$s och andra skriver… + Skicka ett krypterat svar… + Skicka ett svar (okrypterat)… + Anslutningen till servern har tappats. + Meddelanden skickades inte. %1$s eller %2$s nu\? + Meddelanden skickades inte eftersom en okänd session närvarar. %1$s eller %2$s nu\? + Skicka alla igen + Avbryt alla + Skicka oskickade meddelanden igen + Radera oskickade meddelanden + Du har inte behörighet att skriva i det här rummet + Betro + Betro inte + Logga ut + Ignorera + Fingeravtryck (%s): + Detta kan betyda att någon med uppsåt fångar upp din trafik, eller att din mobil inte litar på certifikatet som skickades av servern. + Om serveradministratören har sagt att detta är förväntat, försäkra att fingeravtrycket nedan matchar fingeravtrycket de angav. + Certifikatet har ändrats från ett som var betrott av din mobil. Detta är HÖGST OVANLIGT. Du rekommenderas att INTE ACCEPTERA det nya certifikatet. + Acceptera endast certifikatet om serveradministratören har publicerat ett fingeravtryck som matchar det ovan. + + + 1 valt + %d valda + + INBJUDNA + ANSLUTNA + + Anledning för att rapportera det här innehållet + Avbryt uppladdning + Avbryt nedladdning + + Sök + Inga resultat + MEDDELANDEN + GÅ MED + KATALOG + FAVORITER + LÅG PRIORITET + INBJUDNINGAR + Starta chatt + Skapa rum + Gå med i rum + Gå med i ett rum + Skriv ett rums-ID eller ett rumsalias + + Bläddra i katalogen + Söker i katalog… + + Favorit + Nedprioritera + Glöm + Lägg till en genväg på hemskärmen + + Meddelanden + Användarvillkor + Meddelanden från tredje part + Upphovsrätt + Integritetspolicy + + Telefon + Du kan inte göra detta från element på mobilen + Autentisering krävs + + + Diagnostik för felsökning + Kör tester + Kör… (%1$d av %2$d) + Sätt på + + Sätt på + + Misslyckades att ladda anpassade regler, vänligen försök igen. + Kolla Play-tjänster + APK:n Google Play-tjänster är tillgänglig och uppdaterad. + Element använder Google Play-tjänster för att skicka pushmeddelanden, men den verkar inte vara korrekt konfigurerad: +\n%1$s + Fixa Play-tjänster + + Firebase-token + FCM-token hämtades framgångsrikt: +\n%1$s + Misslyckades att hämta FCM-token: +\n%1$s + [%1$s] +\nDet här felet är ur Elements kontroll, och enligt Google indikerar det här felet att den här enheten har för många appar registrerade med FCM. Felet händer endast i fall då extremt många appar är installerade, så det bör inte påverka normala användare. + [%1$s] +\nDet här felet är ur Elements kontroll. Det kan hända av flera anledningar. Det kanske funkar om du försöker igen senare, du kan kolla så att Google Play-tjänster inte är databegränsad i systeminställningarna, eller att enhetens klocka går rätt, eller så kan det hända på en alternativ ROM. + [%1$s] +\nDet här felet är ur Elements kontroll. Det finns inget Google-konto på telefonen. Vänligen öppna kontohanteraren och lägg till ett Google-konto. + Lägg till konto + + Token-registrering + FCM-token registrerades framgångsrikt på hemservern. + Misslyckades att registrera FCM-token på hemservern: +\n%1$s + + Starta tjänst + + Tjänsten dödades och startades om automatiskt. + Tjänsten misslyckades att starta om + + Starta vid boot + Tjänsten kommer att startas när enheten startas om. + Aktivera start på boot + + Kolla bakgrundsrestriktioner + Bakgrundsrestriktioner är inaktiverade för Element. Detta test bör köras med mobildata (inte Wi-Fi). +\n%1$s + Inaktivera restriktioner + + Batterioptimering + Element påverkas inte av batterioptimering. + Ignorera optimering + + Reducerad sekretess + Den här appen behöver behörighet att köra i bakgrunden + Apparna behöver inte ansluta till hemservern i bakgrunden, det bör reducera batterianvändning + Tänd skärmen i 3 sekunder + Bakgrundssynkronisering + Bakgrundssynkroniseringsläge (experimentellt) + Optimerad för batteri + Användarvillkor + Meddelanden från tredje part + Upphovsrätt + Integritetspolicy + Annat + Kryptografi + Hantering av kryptografiska nycklar + Sessioner + Låt andra användare se när du skriver. + Markdownformatering + Visa läst-indikationer + Tryck på läst-indikationer för en detaljerad lista. + Säker säkerhetskopiering + Sätt upp säker säkerhetskopiering + Återställ säker säkerhetskopiering + Sätt upp på den här enheten + Generera en ny säkerhetskopia eller sätt en ny lösenfras för din existerande säkerhetskopia. + Sessionsinformation + Detta är experimentella funktioner som kan gå sönder på oväntade sätt. Använd varsamt. + Kryptera endast till verifierade sessioner + Algoritm + Sessions-ID + Avsändarens sessionsinformation + Sessions-ID + Sessionsnyckel + Exportera krypteringsnycklar + Exportera rumsnycklar + Exportera + Vänligen skapa en lösenfras för att kryptera de exporterade nycklarna. Du kommer behöva skriva in samma lösenfras för att kunna importera nycklarna. + Hantera nyckelsäkerhetskopiering + + Importera krypteringsnycklar + Importera rumsnycklar + Importera + Kryptera endast till verifierade sessioner + okänd session + Verifiera session + Rummet innehåller okända sessioner + Detta alternativ kräver en tredjepartsapplikation för att spela in meddelandena. + Du har lagt till en ny session \'%s\', vilken begär krypteringsnycklar. + En ny session begär krypteringsnycklar. Sessionsnamn: %1$s +\nSenast sedd: %2$s +\nOm du inte loggade in i en annan session, ignorera denna begäran. + Din overifierade session \'%s\' begär krypteringsnycklar. + En ny session begär krypteringsnycklar. +\nSessionsnamn: %1$s +\nSenast sedd: %2$s +\nOm du inte loggade in i en annan session, ignorera denna begäran. + + Markdown har aktiverats. + Markdown har inaktiverats. + + För att fortsätta använda hemservern %1$s så måste du läsa och godkänna användarvillkoren. + Ingen Matrixsession tillgänglig + + Börja använda nyckelsäkerhetskopiering + Exportera nycklar manuellt + + Säkra din säkerhetskopia med en lösenfras. + Eller säkra din säkerhetskopia med en återställningsnyckel och spara den någonstans säkert. + Dina nycklar säkerhetskopieras. + Det ser ut som att du redan har konfigurerat säker säkerhetskopiering från en annan session. Vill du ersätta den med den du skapar\? + Dina krypteringsnycklar säkerhetskopieras just nu till din hemserver i bakgrunden. Den initiala säkerhetskopieringen kan ta flera minuter. + + + Förlorat din återställningsnyckel\? Du kan sätta upp en ny i inställningarna. + Säkerhetskopieringen kunde inte avkrypteras med den här återställningsnyckeln: vänligen verifiera att du skrev in rätt återställningsnyckel. + + + Återställde en säkerhetskopia med %d nyckel. + Återställde en säkerhetskopia med %d nycklar. + + + %d ny nyckel har lagts till till den här sessionen. + %d nya nycklar har lagts till till den här sessionen. + + + Sessionskrypto är inte aktiverats + + + Återställ från säkerhetskopia + Radera säkerhetskopia + + Nyckelsäkerhetskopiering har blivit korrekt konfigurerad för den här sessionen. + Nyckelsäkerhetskopiering är inte aktiverad på den här sessionen. + Dina nycklar säkerhetskopieras inte från den här sessionen. + + Säkerhetskopian har en signatur från en okänd session med ID %s. + Säkerhetskopian har en giltig signatur från den här sessionen. + Säkerhetskopian har en giltig signatur från den verifierade sessionen %s. + Säkerhetskopian har en giltig signatur från den overifierade sessionen %s + Säkerhetskopian har en ogiltig signatur från den verifierade sessionen %s + Säkerhetskopian har en ogiltig signatur från den overifierade sessionen %s + För att använda nyckelsäkerhetskopiering i den här sessionen, återställ med din lösenfras eller återställningsnyckel nu. + Misslyckades att radera säkerhetskopia (%s) + + Radera säkerhetskopia + Ny nyckelsäkerhetskopia + Börja använda nyckelsäkerhetskopiering + + Säker säkerhetskopiering + Använd nyckelsäkerhetskopiering + + Hantera i nyckelsäkerhetskopieringen + + Sätt upp säker säkerhetskopiering + + Alla nycklar säkerhetskopierade + Algoritm + Att verifiera den här sessionen kommer att markera den som betrodd, och även markera din session som betrodd för den andra parten. + + Verifiera den här sessionen genom att bekräfta att följande emoji visas på den andra partens skärm + Verifiera den här sessionen genom att bekräfta att följande nummer visas på den andra partens skärm + + Du har framgångsrikt verifierat den här sessionen. + Den andra parten avbröt verifikationen. +\n%s + Interaktiv sessionsverifiering + %s vill verifiera din session + + Sessionen känner inte till den överföringen + Sessionen kan inte komma överens om ett nyckelavtal, hash, MAC eller SAS-metod + Visa borttagna meddelanden + Visa en platshållare för borttagna meddelanden + Annan information från tredje part + Pushregler + Inga pushregler satta + Visa dolda händelser i tidslinjen + + Tillåt att svajpa för att svara i tidslinjen + Lägg till en dedikerad flik för olästa aviseringar på startskärmen. + + Aktivera mångordiga loggar. + Vänligen försök igen när du har godkänt användarvillkoren för din hemserver. + + + %1$s, %2$s och %3$d annan har läst + %1$s, %2$s och %3$d andra har läst + + Element behöver behörighet för att spara dina nycklar för totalsträckskryptering i lagringen. +\n +\nVänligen ge tillstånd i nästa popup för att kunna manuellt exportera dina nycklar. + + Du ignorerar inga användare + + Annan + Om du har skapat ett konto på en hemserver så kan du använda ditt Matrix-ID (t.ex. @användare:domän.com) och lösenord nedan. + Detta kan bero på flera orsaker: +\n +\n• Du har ändrat ditt lösenord från en annan session. +\n +\n• Du har tagit bort den här sessionen från en annan session. +\n +\n• Serveradministratören har tagit bort din åtkomst av säkerhetsskäl. + Varning: Din personliga data (inklusive krypteringsnycklar) lagras fortfarande på den här enheten. +\n +\nRensa den om du inte ska använda den här enheten längre, eller vill logga in på ett annat konto. + Den nuvarande sessionen är för användaren %1$s och du försedde uppgifter för användaren %2$s. Detta stöds inte av Element. +\nVänligen rensa först data, och logga sen in på ett annat konto. + + Se alla mina sessioner + Utvecklarläge + Utvecklarläget aktiverar dolda funktioner och kan också göra appen mindre stabil. Endast för utvecklare! + Raseriskakning + Detektionsgräns + Skaka din mobil för att testa detektionsgränsen + Nuvarande session + Andra sessioner + + Misslyckas snabbt + En av följande kan vara äventyrad: +\n +\n - Din hemserver +\n - Hemservern användaren du verifierar är ansluten till +\n - Din eller den andra användarens internetanslutning +\n - Din eller den andra användarens enhet + + Verifiera den här sessionen + Skanna koden med den andra användarens enhet för att säkert verifiera varandra + Tidslinje + + Jämför koden med den som visas på den andra användarens skärm. + Korssignering + Korssignering är aktiverad +\nPrivata nycklar finns på enheten. + Korssignering är aktiverad +\nNycklar är betrodda. +\nPrivata nycklar är inte kända + Korssignering är aktiverad +\nNycklar är inte betrodda + Korssignering är inte aktiverat + + Aktiva sessioner + Visa alla sessioner + Hantera sessioner + Logga ut ur den här sessionen + + Den här sessionen är betrodd för säker kommunikation för att du verifierade den: + + %d aktiv session + %d aktiva sessioner + + + Andra användare kanske inte litar på den + Misslyckades att hämta sessioner + Sessioner + Den här sessionen är betrodd för säker kommunikationen för säker kommunikation för att %1$s (%2$s) verifierade den: + %1$s (%2$s) loggade in i en ny session: + Tills den här användaren litar på den här sessionen så kommer meddelanden skickade till och från den att bli märkta med varningar. Alternativt så kan du manuellt verifiera den. + + + Utvecklarverktyg + Kontodata + Om du inte kan komma åt en existerande session + + Nyckelförfrågningar + + En av följande kan vara äventyrad: +\n +\n- Ditt lösenord +\n- Din hemserver +\n- Den här enheten, eller den andra enheten +\n- Internetuppkopplingen en av enheterna använder +\n +\nVi rekommenderar att du ändrar ditt lösenord och återställningsnyckel i inställningarna omedelbart. + + Sätter upp nyckelsäkerhetskopiering + + + Spara den på ett USB-minne eller en säkerhetskopieringsenhet + Nästan där! Visar den andra enheten samma sköld\? + Misslyckades att importera nycklar + + Aktivera korssignering + Kollar säkerhetskopieringsnyckel + Kollar säkerhetskopieringsnyckel (%s) + Skriv in din lösenfras för säkerhetskopiering för att fortsätta. + använda din återställningsnyckel för säkerhetskopiering + Om du inte känner till din lösenfras för säkerhetskopia så kan du %s. + Återställningsnyckel för säkerhetskopiering + + Förhindra skärmdumpar av appen + Att aktivera den här inställningen lägger till FLAG_SECURE till alla aktiviteter. Starta om appen för att inställningen ska få effekt. + + Använd senaste Element på dina andra enheter; Element Web, Element iOS, Element för Android, eller annan Matrixklient som stöder korssignering + eller en annan Matrixklient som städer korssignering + Använd senaste Element på dina andra enheter: + Tvingar den nuvarande utgående gruppsessionen i ett krypterat rum att kasseras + Säkerhetskopian kunde inte avkrypteras med den här återställningsnyckeln: vänligen verifiera att du skrev in rätt återställningsnyckel. + Sätt upp säker säkerhetskopiering + + Säker säkerhetskopiering + Sätt upp + Skriv in en hemlig fras endast du känner till, och generera en nyckel för säkerhetskopiering. + + From 5bfb2c211aa3714faeffda017dd4920b3dc94f36 Mon Sep 17 00:00:00 2001 From: Slimane Selyan AMIRI Date: Sat, 22 Aug 2020 18:04:55 +0000 Subject: [PATCH 013/257] Added translation using Weblate (Kabyle) --- vector/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 vector/src/main/res/values-kab/strings.xml diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/vector/src/main/res/values-kab/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 385de03f40425d4555ef32693cc3a2f00e4081bb Mon Sep 17 00:00:00 2001 From: Slimane Selyan AMIRI Date: Sat, 22 Aug 2020 18:05:34 +0000 Subject: [PATCH 014/257] Added translation using Weblate (Kabyle) --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 matrix-sdk-android/src/main/res/values-kab/strings.xml diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 6249d5a85ea45cf6c2614da0951473074bf497c0 Mon Sep 17 00:00:00 2001 From: Slimane Selyan AMIRI Date: Sat, 22 Aug 2020 18:19:03 +0000 Subject: [PATCH 015/257] Translated using Weblate (Kabyle) Currently translated at 0.3% (5 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/kab/ --- vector/src/main/res/values-kab/strings.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index a6b3daec93..db3a40b3b6 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -1,2 +1,9 @@ - - \ No newline at end of file + +kab + DZ + Latn + + Asentel aceɛlal + Asentel n yiḍ + Asentel aberkan + From 2fd9333fb0ad2edab9295db85853a1e8d61fbfef Mon Sep 17 00:00:00 2001 From: Slimane Selyan AMIRI Date: Sat, 22 Aug 2020 18:29:54 +0000 Subject: [PATCH 016/257] Translated using Weblate (Kabyle) Currently translated at 7.2% (17 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index a6b3daec93..98f3f5df83 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -1,2 +1,5 @@ - - \ No newline at end of file + +%1$s: %2$s + %1$s t.yuzen tugna. + Tuzneḍ tugna. + From bd033ed5f4b4e57ad2ce9fbf133c1a1b7120600c Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sat, 22 Aug 2020 21:11:52 +0000 Subject: [PATCH 017/257] Translated using Weblate (Kabyle) Currently translated at 7.2% (17 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 98f3f5df83..c8fbe5847c 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -2,4 +2,19 @@ %1$s: %2$s %1$s t.yuzen tugna. Tuzneḍ tugna. + Tinubga n %s + Tinubga-k•m + %1$s yesnulfa-d taxxamt + Tesnulfaḍ-d taxxamt-a + %1$s inced-d %2$s + Tnecdeḍ-d %1$s + %1$s inced-ik-id + %1$s yedda ɣer texxamt + Teddiḍ ɣer texxamt + %1$s yeǧǧa taxxamt + Teǧǧiḍ taxxamt + %1$s yugi/tugi tinubga + Tufiḍ tinubga + %1$s yessufeɣ %2$s + Tessufɣeḍ %1$s From 9e1fe22c19996b32e3f60787b568e6055437fab0 Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 06:37:58 +0000 Subject: [PATCH 018/257] Translated using Weblate (Kabyle) Currently translated at 39.6% (93 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index c8fbe5847c..793e92cebd 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -17,4 +17,75 @@ Tufiḍ tinubga %1$s yessufeɣ %2$s Tessufɣeḍ %1$s + Tbeddleḍ avatar-inek·inem + Anedbal + Aseɣyad + Amezwer + Sagen + + %1$s seg %2$s ɣer %3$s + + Tegguma ad d-tali tugna + + Tansa n yimayl + Aqjun + Amcic + Izem + Aεewdiw + Azara + Ilef + Ilu + Awtul + Apunda + Ayaziḍ + Awarfus + Afekrun + Lḥut + Azayz + Aferteṭṭu + Ajeǧǧig + Aseklu + Agersal + Amaḍal + Ayyur + Agu + Times + Tabanant + Tatteffaḥt + Tazwelt + Akbal + Tapizzat + Angul + Ul + Acmumeḥ + Aṛubut + Acapun + Tisekkadin + Santa + Tasiwant + Amasrag + Tamrint + Asefk + Adlis + Akeryun + Timqestin + Sekkeṛ + Tasarut + Tafḍist + Tiliγri + Anay + Tamacint + Azlalam + Timeẓdit + Balles + Tagitaṛt + Lɣiḍa + Anayna + Tamdeyt + Wennez + Akaram + Amessak + + Qbel + Agwi From a54c1af7cc98778311c2977bc3b96bc19634f802 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 11:59:36 +0000 Subject: [PATCH 019/257] Translated using Weblate (Kabyle) Currently translated at 39.6% (93 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 793e92cebd..4d367a06e7 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -88,4 +88,14 @@ Qbel Agwi + %1$s yuzen amenṭaḍ. + Tuzneḍ amenṭaḍ + + %1$s yekkes agdal i %2$s + Tekkseḍ agdal i %1$s + %1$s igdel %2$s + Tgedleḍ %1$s + %1$s issefsex tinubga n %2$s + Tesfesxeḍ tinubga n %1$s + %1$s ibeddel avatar-is From edd455a772df0cfd8ed055cc54c2f5cf7db13fc8 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 12:12:08 +0000 Subject: [PATCH 020/257] Translated using Weblate (Kabyle) Currently translated at 69.4% (163 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 4d367a06e7..926c33e684 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -98,4 +98,77 @@ %1$s issefsex tinubga n %2$s Tesfesxeḍ tinubga n %1$s %1$s ibeddel avatar-is + %1$s isbadu isem-is i d-ittuseknen ɣer %2$s + Tesbaduḍ isem-ik•im i d-ittuseknen ɣer %1$s + %1$s ibeddel isem-is i d-ittuseknen seg %2$s ɣer %3$s + Tbeddleḍ isem-ik•im i d-ittuseknen seg %1$s ɣer %2$s + %1$s yekkes isem-is i d-ittuseknen (yella %2$s) + Tekkseḍ isem-ik•im i d-ittuseknen (yella %1$s) + %1$s ibeddel asentel ɣer: %2$s + Tbeddleḍ asentel ɣer: %1$s + %1$s ibeddel avatar n texxamt + Tbeddleḍ avatar n texxamt + %1$s ibeddel isem n texxamt ɣer: %2$s + Tbeddleḍ isem n texxamt ɣer: %1$s + %s isɛedda asiwel s tvidyut. + Tesɛeddaḍ asiwel s tvidyut. + %s isɛedda asiwel aɣectan. + Tesɛeddaḍ asiwel aɣectan. + %s yuzen isefka i twila n usiwel. + Tuzneḍ isefka i twila n usiwel. + %s yerra i usiwel. + Terriḍ i usiwel. + %s ifukk asiwel. + Tfukkeḍ asiwel. + akk iɛeggalen n texxamt, segmi d-ttwanecden. + akk iɛeggalen n texxamt, segmi d-rnan. + akk iɛeggalen n texxamt. + yal yiwen. + arussin (%s). + %1$s irmed awgelhen seg yixef ɣer yixef (%2$s) + Tremdeḍ awgelhen seg yixef ɣer yixef (%1$s) + %s ileqqem taxxamt-a. + Tleqqmeḍ taxxamt-a. + + %1$s yessuter asarag VoIP + Tessutreḍ asarag VoIP + Asarag VoIP yebda + Asarag VoIP yekfa + + (avatar daɣen ibeddel) + %1$s yekkes isem n texxamt + Tekkseḍ isem n texxamt + %1$s yekkes asentel n texxamt + Tekkseḍ asentel n texxamt + %1$s yekkes avatar n texxamt + Tekkseḍ avatar n texxamt + Izen ittwakkes + Izen ittwakkes sɣur %1$s + Izen ittwakkes [tamentilt: %1$s] + Izen ittwakkes sɣur %1$s [tamentilt: %2$s] + %1$s ileqqem amaɣnu-ines %2$s + Tleqqmeḍ amaɣnu-inek•inem %1$s + %1$s yuzen tinubga i %2$s akken ad yeddu ɣer texxamt + Tuzneḍ tinubga i %1$s akken ad yeddu ɣer texxamt + %1$s iqbel tinubga i %2$s + Tqebleḍ tinubga i %1$s + + %1$s yerna awiǧit %2$s + Terniḍ awiǧit %1$s + %1$s yekkes awiǧit %2$s + Tekkseḍ awiǧit %1$s + %1$s ibeddel awiǧit %2$s + Tbeddleḍ awiǧit %1$s + + Sagen (%1$) + Tbeddleḍ aswir n tezmert n %1$s. + %1$s ibeddel aswir n tezmert n %2$s. + ** Azmek d awezɣi: %s ** + Ibenk n umazan ur aɣ-d-yuzin ara tisura i yizen-a. + + Tuzzna n yizen d tawezɣit + + Tuccḍa n uẓeṭṭa + Tuccḍa n Matrix + From 64b6b069a4ce40034fe91a5f014008664bdc178b Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 14:29:03 +0000 Subject: [PATCH 021/257] Translated using Weblate (Kabyle) Currently translated at 69.4% (163 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 926c33e684..8d029cc542 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -171,4 +171,8 @@ Tuccḍa n uẓeṭṭa Tuccḍa n Matrix + %1$s yerra amazray i d-iteddun ṣer sdat n texxamt yettban i %2$s + Ad terreḍ amazray n texxamt i d-iteddun ɣer sdat yettban i %1$s + %1$s issefsax tinubga i %2$s i wakken ad d-yekcem ɣer texxamt + Tesfesxeḍ tinubga i %1$s i wakken ad d-yernu ɣer texxamt From c490d6bcd17f38ab42c8ac123bb1c8c87c1dd9d9 Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 14:32:38 +0000 Subject: [PATCH 022/257] Translated using Weblate (Kabyle) Currently translated at 72.3% (170 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 8d029cc542..3717bb997d 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -163,13 +163,13 @@ Sagen (%1$) Tbeddleḍ aswir n tezmert n %1$s. %1$s ibeddel aswir n tezmert n %2$s. - ** Azmek d awezɣi: %s ** + ** Awgelhen d awezɣi: %s ** Ibenk n umazan ur aɣ-d-yuzin ara tisura i yizen-a. - Tuzzna n yizen d tawezɣit + Tuzna n yizen d tawezɣit - Tuccḍa n uẓeṭṭa - Tuccḍa n Matrix + Tuccḍa deg uzeṭṭa + Tuccḍa deg Matrix %1$s yerra amazray i d-iteddun ṣer sdat n texxamt yettban i %2$s Ad terreḍ amazray n texxamt i d-iteddun ɣer sdat yettban i %1$s From f02ee2af27254c1a155e15f1dec58cb845447b56 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 14:33:54 +0000 Subject: [PATCH 023/257] Translated using Weblate (Kabyle) Currently translated at 72.3% (170 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 3717bb997d..bfa5a5c1d1 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -27,7 +27,7 @@ Tegguma ad d-tali tugna - Tansa n yimayl + Tansa imayl Aqjun Amcic Izem @@ -175,4 +175,20 @@ Ad terreḍ amazray n texxamt i d-iteddun ɣer sdat yettban i %1$s %1$s issefsax tinubga i %2$s i wakken ad d-yekcem ɣer texxamt Tesfesxeḍ tinubga i %1$s i wakken ad d-yernu ɣer texxamt + D awezɣi tura ad nuɣal ɣer texxamt tilemt. + + Izen yettwawgelhen + + Uṭṭun n tiliɣri + + Tinubga sɣur %s + Tinubga n texxamt + + %1$s d %2$s + + + %1$s d 1 n wayeḍ + %1$s d %2$d n wiyaḍ + + From 601cf10fb4a88b0cb96facf0ec93911c5a36130e Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 14:38:55 +0000 Subject: [PATCH 024/257] Translated using Weblate (Kabyle) Currently translated at 96.6% (227 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index bfa5a5c1d1..bd23810068 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -175,20 +175,27 @@ Ad terreḍ amazray n texxamt i d-iteddun ɣer sdat yettban i %1$s %1$s issefsax tinubga i %2$s i wakken ad d-yekcem ɣer texxamt Tesfesxeḍ tinubga i %1$s i wakken ad d-yernu ɣer texxamt - D awezɣi tura ad nuɣal ɣer texxamt tilemt. + D awezɣi tura ad nales ad nuɣal ɣer texxamt tilemt. Izen yettwawgelhen Uṭṭun n tiliɣri Tinubga sɣur %s - Tinubga n texxamt + Tinubga ɣer texxamt %1$s d %2$s - %1$s d 1 n wayeḍ - %1$s d %2$d n wiyaḍ + %1$s d 1 wayeḍ + %1$s d %2$d wiyaḍ - + Akeṛmus + Tesremdeḍ awgelhen seg yixef ɣer yixef (alguritm arussin %1$s). + + %s isuter-d ad isenqed tasarut-ik·im, maca amsaɣ-ik·im ur issefrak ara asenqed n tsura deg yidiwenniyen. Ilaq-ak·am useqdec asenqed iqdim n tsura i usenqed n tsura. + + Ɛelleq + + From 8b41b014ee5fa58a0a3e07b91d09cbcb5064a862 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 14:39:09 +0000 Subject: [PATCH 025/257] Translated using Weblate (Kabyle) Currently translated at 96.6% (227 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 88 ++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index bd23810068..766b670d26 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -40,7 +40,7 @@ Ayaziḍ Awarfus Afekrun - Lḥut + Aslem Azayz Aferteṭṭu Ajeǧǧig @@ -198,4 +198,88 @@ Ɛelleq - +Taxxamt tilemt + + + Adebbuz d asawen + Taftilt + Asafag + Amtawi n tazwara: +\nAktar n umiḍan… + Amtawi n tazwara: +\nAktar n uwgelhen + Amtawi n tazwara: +\nAktar n texxamin + Amtawi n tazwara: +\nAktar n texxamin iɣer terniḍ + Amtawi n tazwara: +\nAktar n texxamin iɣer tettwanecdeḍ + Amtawi n tazwara: +\nAktar n texxamin i teǧǧiḍ + Amtawi n tazwara: +\nAktar n tmezdagnutin + Amtawi n tazwara: +\nAktar n yisefka n umiḍan + + Tuzzna n yizen… + Tinubga n %1$s. Tamentilt: %2$s + Tinubga-k•m. Tamentilt: %1$s + %1$s inced %2$s. Tamentilt: %3$s + Tnecdeḍ %1$s. Tamentilt: %2$s + %1$s inced-ik•ikem. Tamentilt: %2$s + %1$s yedda ɣer texxamt. Tamentilt: %2$s + Teddiḍ ɣer texxamt. Tamentilt: %1$s + %1$s yeǧǧa taxxamt. Tamentilt: %2$s + Teǧǧiḍ taxxamt. Tamentilt: %1$s + %1$s yugi tinubga. Tamentilt: %2$s + Tugiḍ tinubga. Tamentilt: %1$s + %1$s yessufeɣ %2$s. Tamentilt: %3$s + Tessufɣeḍ %1$s. Tamentilt: %2$s + %1$s yekkes agdal i %2$s. Tamentilt: %3$s + Tekkseḍ agdal i %1$s. Tamentilt: %2$s + %1$s igdel %2$s. Tamentilt: %3$s + Tgedleḍ %1$s. Tamentilt: %2$s + %1$s yuzen tinubga i %2$s akken ad yeddu ɣer texxamt. Tamentilt: %3$s + Tuzneḍ tinubga i %1$s iwakken ad yeddu ɣer texxamt. Tamentilt: %2$s + %1$s iqbel tinubga i %2$s. Tamentilt: %3$s + Tqebleḍ tinubga i %1$s. Tamentilt: %2$s + %1$s issefsex tinubga n %2$s. Tamentilt: %3$s + Tesfesxeḍ tinubga n %1$s. Tamentilt: %2$s + + + %1$s yerna %2$s d tansa i texxamt-a. + %1$s yerna %2$s d tansiwin i texxamt-a. + + + + Terniḍ %1$s d tansa i texxamt-a. + Terniḍ %1$s d tansiwin i texxamt-a. + + + + %1$s yekkes %2$s am tansa i texxamt-a. + %1$s yekkes %3$s am tansiwin i texxamt-a. + + + + Tekkseḍ %1$s am tansa i texxamt-a. + Tekkseḍ %2$s am tansiwin i texxamt-a. + + + %1$s yerna %2$s terniḍ tekkseḍ %3s am tansiwin i texxamt-a. + Terniḍ %1$s terniḍ tekkseḍ %2$s am tansiwin i texxamt-a. + + %1$s isbadu %2$s am tansa tagejdant i texxamt-a. + Tesbaduḍ %1$s am tansa tagejdant i texxamt-a. + %1$s yekkes tansa tagejdant i texxamt-a. + Tekkseḍ tansa tagejdant i texxamt-a. + + %1$s isireg inebgawen ad ddun ɣer texxamt. + Tsirgeḍ inebgawen ad ddun ɣer texxamt. + %1$s issewḥel inebgawen iwakken ur tteddun ara ɣer texxamt. + Tesweḥleḍ inebgawen iwakken ur tteddun ara ɣer texxamt. + + %1$s yermed awgelhen seg yixef ɣer yixef. + Tremdeḍ awgelhen seg yixef ɣer yixef. + %1$s yermed awgelhen seg yixef ɣer yixef (alguritm %2$s ur yettwassen ara). + From e87bd16b6b972a692e13267ac9ccbd5b6e631c76 Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 06:35:09 +0000 Subject: [PATCH 026/257] Translated using Weblate (Kabyle) Currently translated at 24.4% (452 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/kab/ --- vector/src/main/res/values-kab/strings.xml | 483 +++++++++++++++++++++ 1 file changed, 483 insertions(+) diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index db3a40b3b6..a6666ac066 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -6,4 +6,487 @@ Asentel aceɛlal Asentel n yiḍ Asentel aberkan + Awennez n umeẓlu + Iznan + Taxxamt + Iɣewwaren + Amazray + Asenqed n tɣimit + + Tebɣiḍ s tidet\? + Asali... + + IH + Sefsex + Sekles + Ffeɣ + Azen + Nɣel + Ɛawed azen + Sfeḍ + Tanebdurt + Sader + Bḍu + Ticki + Wali aɣbalu + Kkes + Beddel isem + Ula yiwen + Ḥwi + Ffeɣ seg tuqqna + Asiwel urmid + ɣer + Agi + + + Ur tesεiḍ ara tisirag ad tebduḍ asireg s usiwel deg texxamt-a + Tukksa n uwiǧit ur teddi ara + neɣ + Nced + Beṛṛa n tuqqna + Qbel + Zgel + Immed + Sefsex + Ttu + Senqed + Agwi + + Ffeɣ + Tigawin + Ffeɣ seg tuqqna + Creḍ kullec yettwaɣra + Amazray + Ldi + Mdel + Nɣel + Sens + + Asentem + Asmigel + Tuccḍa + Yedda + + Agejdan + Ilɣa + Ismenyifen + Imdanen + Timɣiwent + Timɣiwnin + + Inced-d + Tazwart taddayt + Ilɣa n unagraw + + Ulac igmad + Timɣiwent + Akaram n texxamt + Nced + Timɣiwnin + Azen iɣmisen + Rnu ɣer texxamt + Isem n useqdac + Rnu amiḍan + Ffeɣ seg tuqqna + URL n uqeddac n timagit + Nadi + + Ur yeddi ara usiwel ssebba n uqeddac ur nettuswel ara akken iwata + Tiliɣri + Uɣal ɣer deffir + Qqen s unekcum asuf + Rnu amiḍan + Azen + Zgel + Azen imayl n uwennez + Uɣal ɣer ugdil n tuqqna + Awal uffir + Awal uffir amaynut + Tansa n yimayl + Sneqdeɣ tansa-inu n yimayl + Awal uffir amaynut ilaq ad yettusekcem. + Asenqed n tansa n yimayl ur yeddi ara: wali ma yella tsateḍ ɣef useɣwen yellan deg yimayl + Asuter n tsarut yettwazen. + + Aneẓli + Alemmas + Iḍelli + Ass-a + + Isawalen + Asiwel yekfa + Talɣut + IH + Kemmel + + Sfeḍ + Rnu + Taskant + Agi + + Ffeɣ seg texxamt + Snulfu-d + + Srid + Beṛṛa n tuqqna + Arurmid + Iznan usligen + Nced + Agi + Asefsex n tigtin + Suffeɣ + Abder + Ṣubb deg usellun-ik·im\? + Ṣubb deg usellun + + + Ttu + + Taɣẓint + + Nadi + Azen izen yettuwgelhen… + Azen tiririt yettuwgelhen… + Ur tesεiḍ ara tasiregt ad d-tsuffɣeḍ deg texxamt-a + Ittkel + Tuffɣa + Ttu + Imdanen + Ifuyla + Iɣewwaren + Nadi + Sizdeg iɛeggalen n texxamt + Ulac igmad + Bdu adiwenni + Rnu taxxamt + Iznan i meṛṛa (sɛan ṣṣut) + Iznan i meṛṛa + Sens imesli + Asmenyif + Adiwenni uslig + Iznan + Iɣewwaren + Lqem + Lqem %s + Izerfan ttwaḥerzen + Sken isem + Imayl + Tiliɣri + Rnu uṭṭun n tiliɣri + Rmed + + Rmed + + Rnu amiḍan + + Amagnu + Imesli i yilɣa + Sens ilɣa i umiḍan-a + Iznan yettwaznen s Bot + + Lqem + Izerfan ttwaḥerzen + Ilɣa + Iseqdacen yettunfen + Nniḍen + Talqayt + Awgelhan + Azen ilɣa yettuszemlen + Sefrek + Sens amiḍan + Tagrut + Tiselḍin + Azen isefka n tesleḍt + ID + Isem azayez + Timeẓri taneggarut + Asesteb + Awal uffir: + Azen + + Iqqen am + Aqeddac n timagit + Amsefrak n umsidef + + Imsidaf ttwasensen + "Agrudem n useqdac " + Tutlayt + Asenqed yettṛaǧu + Ma ulac aɣilif, senqed imayl-ik/im syen sit ɣef useɣwen i yellan. Akken ara yemmed waya, sit ad tkemmleḍ. + Awal uffir + Beddel awal n uffir + Awal uffir amiran + Awal uffir amaynut + Tangalt + Fren + Fren + Lbenna + Yal tikkelt + + Isem n texxamt + Asmenyif + Tazwart taddayt + Ula yiwen + + Ilɣa + Anwa i izemren ad d-iɣer amazray\? + Anwa i izemren ad d-yernu ɣer texxamt-a\? + + Yal yiwen + Iɛeggalen kan (segmi yebda ufran n textiṛit-a) + Iɛeggalen kan (segmi ara d-ttwanecden) + Iɛeggalen kan (segmi ara d-ttwarnun) + + Ala imdanen i d-yettusnubegten + Iseqdacen i yettwagin + Talqayt + Tinarimin + Asulay n temɣiwent d arussin + Asentel + + Asulay n tqimit + Asulay n tqimit + Tasarut n tɣimit + Asenqed + Sifeḍ tisura n texxamt E2E + Sifeḍ tisura n texxamt + Sifeḍ + Kter tisura n texxamt E2E + Kter tisura n texxamt + Kter + Yettwasenqed + ulac + + Senqed + Tabdart taberkant + Asenqed n tɣimit + URL n uqeddac agejdan + + %d n ulɣu + %d n ilɣa + + + Taxxamt + Nek + Tuɣzi n tsefsit + Amagnu + Isem-ik·im yettwaskanen + URL n avatar-inek·inem + Asulay-ik·m n useqdac + Asentel-inek·inem + Asulay n yiwiǧit + Asulay n texxamt + + + Sireg + Timerna n uwiǧit ulamek. + Tuzna n usuter ur teddi ara. + Ilaq ad yili uswir n tezmert d ummid ufrir. + Ulac-ik/ikem deg texxamt-a. + Ur tesεiḍ ara tasiregt ad tgeḍ ayagi deg texxamt-a. + Sefrek imsidaf + Senqed + Bḍu + Ttu + + Ɣur-k·m! + Tuccḍa n tladna + Yeskan tigawt + Agi aseqdac s usulay i d-yettunefken + Sbadu aswir iǧehden n useqdac + Aseqdac Deops s usulay i d-yettunefken + Inced iseqdacen s tikci n usulay i texxamt tamirant + Ffeɣ seg texxamt + Suffeɣ aseqdac s usulay i d-yettunefken + Ibeddel isem-inek·inem yettwaskanen + Insa + Snulfu-d + Rnu tamɣiwent + Amedya + amedya + + Agejdan + Imdanen + Timɣiwent + Timɣiwent + Yettwancad + Tettuḍ taxxamt + + Sens amiḍan + Sens amiḍan + + Aqeddac-a agejdan iɛedda yiwet seg tlisa-ines tiɣbula. + + Aqeddac-a agejdan yewweḍ ɣer talast n useqdac urmid n wayyur. + + snefli + fneẓ + + Yal ass + Sentem tafyirt tuffirt + Sekcem tafyirt tuffirt + Bdu aseqdec n uḥraz n tsarut + Sifeḍ s ufus tisura + + Immed + Bḍu + Semselsi + Tebɣiḍ s tidet\? + Tiririt seg uḥraz + Kkes aḥraz + + Kkes aḥraz + Bdu aseqdec n uḥraz n tsarut + + Akk tisura ttwaḥerzent + Lqem + Tuttra n usenqed i d-ikecmen + Yettwasenqed! + Iznan iɣellsanen akked useqdac-a ttwawgelhen seg yixef ɣer yixef yerna yiwen ur yezmir ad ten-iɣeṛ. + Awi-t + + Asuter n usenqed + Ẓreg + Err + + Ɛreḍ tikkelt-nniḍen + Timɣiwent + Izen yettwakksen + Sken-d iznan yettwakksen + Beddel + Timɣiwent + Iznan usligen + + Akaram n texxamt + Amatu + Ismenyifen + Taɣellist & tbaḍnit + Ameslaw & Tavidyut + Tallalt & Ɣef + + + Sken-d ineḍruyen yeffren deg uzray + + Iznan usligen + + Tiwtilin n useqdec + Snifel aqeddac n timagit + Afaylu + Anermis + Takamiṛatt + Timidelt + Iznan i meṛṛa (sɛan ṣṣut) + Iznan i meṛṛa + Sens imesli + Iɣewwaren + Rnu inurifen + Kkes seg yinuraf + Aha bdu tura + + Nniḍen + Kemmel + Jerred + Kcem + Γer sdat + Imayl + Awal uffir amaynut + + Ɣur-k·m! + Kemmel + + Sneqdeɣ tansa-inu n yimayl + + Tammug akken iwata! + Awal uffir-inek/inem yettuwennez. + Asmigel + Imayl + Imayl (Afrayan) + Γer sdat + + Γer sdat + + Γer sdat + + Isem n useqdac + Awal uffir + Γer sdat + Asmigel + Asulay n Matrix + Qqen + Qqen + Awal uffir + Sfeḍ isefka udmawanen + Sfeḍ meṛṛa isefka + + Iɣewwaren + Yerna ¯\\_(ツ)_/¯ ɣer yizen n uḍris arewway + + Msaḍan + Ur msaḍan ara + Afaylu + Tesfesxeḍ + Tqebleḍ + Asuter n usenqed + Asenqed n tɣimit + Taɣellist + Ilɣa + Ffeɣ seg texxamt + Inedbalen + Sagen + Inced-d + Iseqdacen + + Ɛeddi ɣer tɣuri n wawwaḍ + + Amazray + + Awgelhen seg yixef ɣer yixef ur yeddi ara + Rmed awgelhen\? + Senqed anekcam-a + Iseqdacen-nniḍen yezmer ur tettamnen ara + Senqed + Yettwasenqed + Asmigel + + Yettwattkal + Ur yettwattkal ara + + Ales awennez n tsura + + Ih + Uhu + + Sentem tukksa + Smiren + + Anekcam amaynut. D kečč/kemm\? + Tasarut-ik·im n uɛeddi + Fakk + + Awgelhen ur yeddi ara + Awgelhen ur yermid ara + Iznan ideg yella @taxxamt + Iznan yettwawgelhen deg yidiwenniyen usriden + Iznan yettwawgelhen deg yidiwenniyen n ugraw + Mi ara ttwaleqqment texxamin + Yuzen izen d aḍris aččuran war ma isegza-t s tukksa n tecreḍt + + Amiḍan-a yettuḥbes. + + Yella uleqqem n uwgelhen + Senqed iman-ik•im d wiyaḍ akken ad qqimen yidiwenniyen-ik•im d iɣellsanen + + Seqdec tasarut n uɛeddi + Ur yettwawgelhen ara + Senqed ansi i d-tkecmeḍ + Senqed akk tiqimiyin-ik·im i wakken ad tḍemneḍ amiḍan-ik·m & yiznan d iɣelsanen + Senqed s ufus s ttawil n uḍris + Azen + Sbadu + Sekles tasarut-ik·im n tɣellist + Sbadu tafyirt taɣelsant + Sekles tasarut-ik·im n tɣellist + Isem n texxamt + Tura, Riot d aferdis! + Sefesex tinnubga From 30b92efcc67aa77ed0de8ae43ebeb856abd156ee Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 14:34:47 +0000 Subject: [PATCH 027/257] Translated using Weblate (Kabyle) Currently translated at 24.4% (452 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/kab/ --- vector/src/main/res/values-kab/strings.xml | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index a6666ac066..7d6d1b9033 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -489,4 +489,46 @@ Isem n texxamt Tura, Riot d aferdis! Sefesex tinnubga + Asentel Status.im + + Amtawi… + Timesliwt n yineḍruyen + Ilɣuten isusamen + + Tilɣa ɣef uɛeggal + Aneqqis n ubug + Tilɣa ɣef tmezdagnut + Azen amenṭaḍ + Akles n tsura + Seqdec akles n tsura + Akles n tsura ur ifukk ara, ttxil rǧu… + Ad tesruḥeḍ iznan-ik•im yettwawgelhen ma teffɣeḍ tura + Akles n tsura yetteddu. Ma teffɣeḍ tura, ad tesruḥeḍ anekcum ɣer yiznan-ik•im yettwawgelhen. + Akles aɣellsan n tsura ilaq ad yermed deg tɣimiyin-ik•im akk akken ur tesruḥuḍ ara anekcum ɣer yiznan-ik•im yettwawgelhen. + Ur bɣiɣ ara iznan-iw yettwawgelhen + Akles n tsura… + Seqdec akles n tsura + Kles + Ad tesruḥeḍ anekcum ɣer yiznan-ik•im yettwawgelhen anagar ma tkelseḍ tisura-inek•inem send tuffɣa. + Qqim + Mmeslay + Sfeḍ + Sɛeddi + Aseɣwen imezgi + Sken aɣbalu yettwazemken + Mel agbur + Taɣect + Tavidyut + Ulamek ad yebdu usiwel, ttxil ɛreḍ ticki + Asarag ha-t-an itteddu! + Bdu timlilit s tvidyut + Bdu timlilit tameslawt + Timlilit s useqdec n tsertiyin n tɣellist d tsiregt n Jitsi. Medden akk i yellan deg texxamt ad ẓren tinubga i tmerniwt mi ara d-teḍru temlilit. + Ulamek ad yebdu usiwel + Ur tezmireḍ ara ad tesɛeddiḍ asiwel i yima-ik•im + Ur tezmireḍ ara ad tesɛeddiḍ asiwel i yiman-ik•im, rǧu ad qeblen yimettekkiyen tinubga + Talɣut ɣef tɣimit + Timerniwt n uwiǧit ur teddi ara + Izen yettwawgelhen + From 84854d93825efb0d3d177aa20889072298c4b72b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 10:14:00 +0200 Subject: [PATCH 028/257] Add entry in changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 2f850c8a3c..e0f0780270 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ SDK API changes ⚠️: - Build 🧱: - - + - Some dependencies have been upgraded (coroutine, recyclerView, appCompat, core-ktx, firebase-messaging) Other changes: - From 50495ef604e878f8050bc636e5c5717bc847ee0a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 11:12:19 +0200 Subject: [PATCH 029/257] Improve algo --- .../features/settings/VectorSettingsGeneralFragment.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index e4120e8133..e225f61c4f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -145,12 +145,13 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { session.rx() .liveUser(session.myUserId) .unwrap() - .distinctUntilChanged { user -> user.displayName } + .map { it.displayName ?: "" } + .distinctUntilChanged() .observeOn(AndroidSchedulers.mainThread()) - .subscribe { user -> + .subscribe { displayName -> mDisplayNamePreference.let { - it.summary = user.displayName ?: "" - it.text = user.displayName ?: "" + it.summary = displayName + it.text = displayName } } .disposeOnDestroyView() From 96cf5d2105127f4e0349556449f498abbe58e905 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 14:32:43 +0200 Subject: [PATCH 030/257] Cleanup: propoerly inject things to PushRulesFragment and move PushRulesController to its own file --- .../im/vector/app/core/di/FragmentModule.kt | 6 +++ .../settings/push/PushRulesController.kt | 44 +++++++++++++++++++ .../settings/push/PushRulesFragment.kt | 29 ++---------- 3 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 1aa9902137..591d1c0474 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -102,6 +102,7 @@ import im.vector.app.features.settings.devtools.OutgoingKeyRequestListFragment import im.vector.app.features.settings.ignored.VectorSettingsIgnoredUsersFragment import im.vector.app.features.settings.locale.LocalePickerFragment import im.vector.app.features.settings.push.PushGatewaysFragment +import im.vector.app.features.settings.push.PushRulesFragment import im.vector.app.features.share.IncomingShareFragment import im.vector.app.features.signout.soft.SoftLogoutFragment import im.vector.app.features.terms.ReviewTermsFragment @@ -282,6 +283,11 @@ interface FragmentModule { @FragmentKey(VectorSettingsLabsFragment::class) fun bindVectorSettingsLabsFragment(fragment: VectorSettingsLabsFragment): Fragment + @Binds + @IntoMap + @FragmentKey(PushRulesFragment::class) + fun bindPushRulesFragment(fragment: PushRulesFragment): Fragment + @Binds @IntoMap @FragmentKey(VectorSettingsPreferencesFragment::class) diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt new file mode 100644 index 0000000000..a8a1ab2e17 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.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.app.features.settings.push + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.ui.list.genericFooterItem +import javax.inject.Inject + +class PushRulesController @Inject constructor( + private val stringProvider: StringProvider +) : TypedEpoxyController() { + + override fun buildModels(data: PushRulesViewState?) { + data?.let { + it.rules.forEach { + pushRuleItem { + id(it.ruleId) + pushRule(it) + } + } + } ?: run { + genericFooterItem { + id("footer") + text(stringProvider.getString(R.string.settings_push_rules_no_rules)) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt index 44cb5d8ea2..c361e21254 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt @@ -17,7 +17,6 @@ package im.vector.app.features.settings.push import android.os.Bundle import android.view.View -import com.airbnb.epoxy.TypedEpoxyController import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -25,19 +24,18 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.core.resources.StringProvider -import im.vector.app.core.ui.list.genericFooterItem import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import javax.inject.Inject // Referenced in vector_settings_notifications.xml -class PushRulesFragment : VectorBaseFragment() { +class PushRulesFragment @Inject constructor( + private val epoxyController: PushRulesController +) : VectorBaseFragment() { override fun getLayoutResId() = R.layout.fragment_generic_recycler private val viewModel: PushRulesViewModel by fragmentViewModel(PushRulesViewModel::class) - private val epoxyController by lazy { PushRulesController(StringProvider(requireContext().resources)) } - override fun onResume() { super.onResume() (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_push_rules) @@ -56,23 +54,4 @@ class PushRulesFragment : VectorBaseFragment() { override fun invalidate() = withState(viewModel) { state -> epoxyController.setData(state) } - - class PushRulesController(private val stringProvider: StringProvider) : TypedEpoxyController() { - - override fun buildModels(data: PushRulesViewState?) { - data?.let { - it.rules.forEach { - pushRuleItem { - id(it.ruleId) - pushRule(it) - } - } - } ?: run { - genericFooterItem { - id("footer") - text(stringProvider.getString(R.string.settings_push_rules_no_rules)) - } - } - } - } } From 69e9a79ac1885335a6c55a1e5a547d5ee0892aa4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 14:49:42 +0200 Subject: [PATCH 031/257] Inject StringProvider instead of Context --- .../membership/RoomDisplayNameResolver.kt | 19 ++++++++++--------- .../sdk/internal/util/StringProvider.kt | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt index d11226bdb1..942da9995e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.session.room.membership -import android.content.Context +import io.realm.Realm import org.matrix.android.sdk.R import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel @@ -34,14 +34,15 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrNull import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId -import io.realm.Realm +import org.matrix.android.sdk.internal.util.StringProvider import javax.inject.Inject /** * This class computes room display name */ -internal class RoomDisplayNameResolver @Inject constructor(private val context: Context, - @UserId private val userId: String +internal class RoomDisplayNameResolver @Inject constructor( + private val stringProvider: StringProvider, + @UserId private val userId: String ) { /** @@ -89,7 +90,7 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context: .findFirst() ?.displayName } else { - context.getString(R.string.room_displayname_room_invite) + stringProvider.getString(R.string.room_displayname_room_invite) } } else if (roomEntity?.membership == Membership.JOIN) { val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst() @@ -108,13 +109,13 @@ internal class RoomDisplayNameResolver @Inject constructor(private val context: } val otherMembersCount = otherMembersSubset.count() name = when (otherMembersCount) { - 0 -> context.getString(R.string.room_displayname_empty_room) - 1 -> resolveRoomMemberName(otherMembersSubset[0], roomMembers) - 2 -> context.getString(R.string.room_displayname_two_members, + 0 -> stringProvider.getString(R.string.room_displayname_empty_room) + 1 -> resolveRoomMemberName(otherMembersSubset[0], roomMembers) + 2 -> stringProvider.getString(R.string.room_displayname_two_members, resolveRoomMemberName(otherMembersSubset[0], roomMembers), resolveRoomMemberName(otherMembersSubset[1], roomMembers) ) - else -> context.resources.getQuantityString(R.plurals.room_displayname_three_and_more_members, + else -> stringProvider.getQuantityString(R.plurals.room_displayname_three_and_more_members, roomMembers.getNumberOfJoinedMembers() - 1, resolveRoomMemberName(otherMembersSubset[0], roomMembers), roomMembers.getNumberOfJoinedMembers() - 1) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt index 902d7d3316..9233b2b807 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringProvider.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk.internal.util import android.content.res.Resources -import androidx.annotation.ArrayRes import androidx.annotation.NonNull +import androidx.annotation.PluralsRes import androidx.annotation.StringRes import dagger.Reusable import javax.inject.Inject @@ -56,8 +56,8 @@ internal class StringProvider @Inject constructor(private val resources: Resourc return resources.getString(resId, *formatArgs) } - @Throws(Resources.NotFoundException::class) - fun getStringArray(@ArrayRes id: Int): Array { - return resources.getStringArray(id) + @NonNull + fun getQuantityString(@PluralsRes resId: Int, quantity: Int, vararg formatArgs: Any?): String { + return resources.getQuantityString(resId, quantity, *formatArgs) } } From efa3aa5cf8e24726c18ce4a3493feff618db2e13 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 15:08:52 +0200 Subject: [PATCH 032/257] Stop using internal context of VectorLocal in CallHeadsUpActionReceiver... --- .../call/service/CallHeadsUpActionReceiver.kt | 22 ++++++------------- .../app/features/settings/VectorLocale.kt | 2 +- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt b/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt index 179ba288eb..04e7401e6c 100644 --- a/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt @@ -21,8 +21,6 @@ import android.content.Context import android.content.Intent import im.vector.app.core.di.HasVectorInjector import im.vector.app.features.call.WebRtcPeerConnectionManager -import im.vector.app.features.notifications.NotificationUtils -import im.vector.app.features.settings.VectorLocale.context import timber.log.Timber class CallHeadsUpActionReceiver : BroadcastReceiver() { @@ -32,20 +30,14 @@ class CallHeadsUpActionReceiver : BroadcastReceiver() { const val CALL_ACTION_REJECT = 0 } - private lateinit var peerConnectionManager: WebRtcPeerConnectionManager - private lateinit var notificationUtils: NotificationUtils - - init { - val appContext = context.applicationContext - if (appContext is HasVectorInjector) { - peerConnectionManager = appContext.injector().webRtcPeerConnectionManager() - notificationUtils = appContext.injector().notificationUtils() - } - } - override fun onReceive(context: Context, intent: Intent?) { + val peerConnectionManager = (context.applicationContext as? HasVectorInjector) + ?.injector() + ?.webRtcPeerConnectionManager() + ?: return + when (intent?.getIntExtra(EXTRA_CALL_ACTION_KEY, 0)) { - CALL_ACTION_REJECT -> onCallRejectClicked() + CALL_ACTION_REJECT -> onCallRejectClicked(peerConnectionManager) } // Not sure why this should be needed @@ -56,7 +48,7 @@ class CallHeadsUpActionReceiver : BroadcastReceiver() { // context.stopService(Intent(context, CallHeadsUpService::class.java)) } - private fun onCallRejectClicked() { + private fun onCallRejectClicked(peerConnectionManager: WebRtcPeerConnectionManager) { Timber.d("onCallRejectClicked") peerConnectionManager.endCall() } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt index d2f92e300e..b9d81ab005 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt @@ -52,7 +52,7 @@ object VectorLocale { var applicationLocale = defaultLocale private set - lateinit var context: Context + private lateinit var context: Context /** * Init this object From 116e6fb3c07ca53d64f60f12af453918bd4fc312 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 15:50:47 +0200 Subject: [PATCH 033/257] Call restart() extension --- .../java/im/vector/app/core/platform/VectorBaseActivity.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 11a6e326ac..856e84ea14 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -60,6 +60,7 @@ import im.vector.app.core.dialogs.UnrecognizedCertificateDialog import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.observeNotNull +import im.vector.app.core.extensions.restart import im.vector.app.core.extensions.vectorComponent import im.vector.app.core.utils.toast import im.vector.app.features.MainActivity @@ -79,10 +80,10 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.themes.ThemeUtils import im.vector.app.receivers.DebugReceiver -import org.matrix.android.sdk.api.failure.GlobalError import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable +import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber import kotlin.system.measureTimeMillis @@ -198,8 +199,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { configurationViewModel.activityRestarter.observe(this, Observer { if (!it.hasBeenHandled) { // Recreate the Activity because configuration has changed - startActivity(intent) - finish() + restart() } }) pinLocker.getLiveState().observeNotNull(this) { From 252df0f7a94b6180145281a1edd0809e2109b44c Mon Sep 17 00:00:00 2001 From: notramo Date: Mon, 24 Aug 2020 14:51:10 +0000 Subject: [PATCH 034/257] Mention thousands of public servers in Play Store --- vector/src/main/play/listings/en-US/full_description.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/play/listings/en-US/full_description.txt b/vector/src/main/play/listings/en-US/full_description.txt index e2164a786f..e939b75bb7 100644 --- a/vector/src/main/play/listings/en-US/full_description.txt +++ b/vector/src/main/play/listings/en-US/full_description.txt @@ -13,7 +13,7 @@ Element is able to do all this because it operates on Matrix - the standard for Element puts you in control by letting you choose who hosts your conversations. From the Element app, you can choose to host in different ways: -1. Get a free account on the matrix.org public server +1. Get a free account on the matrix.org public server hosted by the Matrix developers, or choose from thousands of public servers hosted by volunteers 2. Self-host your account by running a server on your own hardware 3. Sign up for an account on a custom server by simply subscribing to the Element Matrix Services hosting platform @@ -27,4 +27,4 @@ Element puts you in control by letting you choose who hosts your conversations. COMPLETE COMMUNICATION: Messaging, voice and video calls, file sharing, screen sharing and a whole bunch of integrations, bots and widgets. Build rooms, communities, stay in touch and get things done. -EVERYWHERE YOU ARE: Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://app.element.io. \ No newline at end of file +EVERYWHERE YOU ARE: Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://app.element.io. From ed98613b2d9c82d6dd36b705456043f078ea2712 Mon Sep 17 00:00:00 2001 From: Tobias Preuss Date: Wed, 19 Aug 2020 22:59:57 +0200 Subject: [PATCH 035/257] Use File extension functions to make code more concise. + This change replaces a few usages of ByteArrayInputStream, FileInputStream, FileOutputStream with their equivalent Kotlin extension functions. --- CHANGES.md | 2 +- .../sdk/internal/crypto/AttachmentEncryptionTest.kt | 3 +-- .../crypto/attachments/MXEncryptedAttachments.kt | 3 +-- .../android/sdk/internal/crypto/store/db/Helper.kt | 3 +-- .../sdk/internal/session/content/UploadContentWorker.kt | 9 +++------ .../internal/session/securestorage/SecretStoringUtils.kt | 2 +- .../org/matrix/android/sdk/internal/util/FileSaver.kt | 3 +-- .../im/vector/app/core/glide/VectorGlideModelLoader.kt | 3 +-- .../im/vector/app/core/utils/ExternalApplicationsUtil.kt | 4 ++-- .../features/notifications/NotificationDrawerManager.kt | 3 +-- 10 files changed, 13 insertions(+), 22 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d3a16c9b29..a9f2e896aa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,7 +20,7 @@ Build 🧱: - Some dependencies have been upgraded (coroutine, recyclerView, appCompat, core-ktx, firebase-messaging) Other changes: - - + - Use File extension functions to make code more concise (#1996) Changes in Element 1.0.5 (2020-08-21) =================================================== diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt index 05dbc40e1e..cb24cbb242 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt @@ -29,7 +29,6 @@ import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters -import java.io.ByteArrayInputStream import java.io.InputStream /** @@ -46,7 +45,7 @@ class AttachmentEncryptionTest { val inputStream: InputStream inputStream = if (`in`.isEmpty()) { - ByteArrayInputStream(`in`) + `in`.inputStream() } else { val memoryFile = MemoryFile("file" + System.currentTimeMillis(), `in`.size) memoryFile.outputStream.write(`in`) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt index cec1480d7b..a6d95cc87a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -21,7 +21,6 @@ import android.util.Base64 import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey import timber.log.Timber -import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream import java.security.MessageDigest @@ -179,7 +178,7 @@ internal object MXEncryptedAttachments { return null } - return ByteArrayInputStream(outputStream.toByteArray()) + return outputStream.toByteArray().inputStream() .also { Timber.v("Decrypt in ${System.currentTimeMillis() - t0}ms") } } catch (oom: OutOfMemoryError) { Timber.e(oom, "## decryptAttachment() failed: OOM") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt index 978c82303e..67e06b5455 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt @@ -21,7 +21,6 @@ import android.util.Base64 import io.realm.Realm import io.realm.RealmConfiguration import io.realm.RealmObject -import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.ObjectOutputStream import java.util.zip.GZIPInputStream @@ -96,7 +95,7 @@ fun deserializeFromRealm(string: String?): T? { } val decodedB64 = Base64.decode(string.toByteArray(), Base64.DEFAULT) - val bais = ByteArrayInputStream(decodedB64) + val bais = decodedB64.inputStream() val gzis = GZIPInputStream(bais) val ois = SafeObjectInputStream(gzis) return ois.use { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index 6d354cdcbe..720269404f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -42,10 +42,7 @@ import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import org.matrix.android.sdk.internal.worker.getSessionComponent import timber.log.Timber -import java.io.ByteArrayInputStream import java.io.File -import java.io.FileInputStream -import java.io.FileOutputStream import java.util.UUID import javax.inject.Inject @@ -130,7 +127,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter val contentUploadResponse = if (params.isEncrypted) { Timber.v("Encrypt thumbnail") notifyTracker(params) { contentUploadStateTracker.setEncryptingThumbnail(it) } - val encryptionResult = MXEncryptedAttachments.encryptAttachment(ByteArrayInputStream(thumbnailData.bytes), thumbnailData.mimeType) + val encryptionResult = MXEncryptedAttachments.encryptAttachment(thumbnailData.bytes.inputStream(), thumbnailData.mimeType) uploadedThumbnailEncryptedFileInfo = encryptionResult.encryptedFileInfo fileUploader.uploadByteArray(encryptionResult.encryptedByteArray, "thumb_${attachment.name}", @@ -176,7 +173,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter cacheFile.createNewFile() cacheFile.deleteOnExit() - val outputStream = FileOutputStream(cacheFile) + val outputStream = cacheFile.outputStream() outputStream.use { inputStream.copyTo(outputStream) } @@ -203,7 +200,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter Timber.v("Encrypt file") notifyTracker(params) { contentUploadStateTracker.setEncrypting(it) } - val encryptionResult = MXEncryptedAttachments.encryptAttachment(FileInputStream(cacheFile), attachment.getSafeMimeType()) + val encryptionResult = MXEncryptedAttachments.encryptAttachment(cacheFile.inputStream(), attachment.getSafeMimeType()) uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo fileUploader diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt index 2ae115f325..8eab44366c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt @@ -219,7 +219,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte @RequiresApi(Build.VERSION_CODES.M) private fun decryptStringM(encryptedChunk: ByteArray, keyAlias: String): String { - val (iv, encryptedText) = formatMExtract(ByteArrayInputStream(encryptedChunk)) + val (iv, encryptedText) = formatMExtract(encryptedChunk.inputStream()) val secretKey = getOrGenerateSymmetricKeyForAliasM(keyAlias) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt index 27625d90bc..da524cc1b2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.util import androidx.annotation.WorkerThread import java.io.File -import java.io.FileOutputStream import java.io.InputStream /** @@ -27,7 +26,7 @@ import java.io.InputStream */ @WorkerThread fun writeToFile(inputStream: InputStream, outputFile: File) { - FileOutputStream(outputFile).use { + outputFile.outputStream().use { inputStream.copyTo(it) } } diff --git a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt index 295609548f..9ac8a4d3bc 100644 --- a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt +++ b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt @@ -31,7 +31,6 @@ import okhttp3.OkHttpClient import okhttp3.Request import timber.log.Timber import java.io.File -import java.io.FileInputStream import java.io.IOException import java.io.InputStream @@ -97,7 +96,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde Timber.v("Load data: $data") if (data.isLocalFile() && data.url != null) { val initialFile = File(data.url) - callback.onDataReady(FileInputStream(initialFile)) + callback.onDataReady(initialFile.inputStream()) return } val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver() diff --git a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt index b314401138..b1c63a406a 100644 --- a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt +++ b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt @@ -518,8 +518,8 @@ fun saveFileIntoLegacy(sourceFile: File, dstDirPath: File, outputFilename: Strin var outputStream: FileOutputStream? = null try { dstFile.createNewFile() - inputStream = FileInputStream(sourceFile) - outputStream = FileOutputStream(dstFile) + inputStream = sourceFile.inputStream() + outputStream = dstFile.outputStream() val buffer = ByteArray(1024 * 10) var len: Int while (inputStream.read(buffer).also { len = it } != -1) { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 98d35dc764..e689f9df3f 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -32,7 +32,6 @@ import org.matrix.android.sdk.api.session.content.ContentUrlResolver import me.gujun.android.span.span import timber.log.Timber import java.io.File -import java.io.FileInputStream import java.io.FileOutputStream import javax.inject.Inject import javax.inject.Singleton @@ -494,7 +493,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context try { val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME) if (file.exists()) { - FileInputStream(file).use { + file.inputStream().use { val events: ArrayList? = currentSession?.loadSecureSecret(it, KEY_ALIAS_SECRET_STORAGE) if (events != null) { return events.toMutableList() From 52cf4d24d36e38d2fc63c662915637e7a4a4f068 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 18:05:11 +0200 Subject: [PATCH 036/257] Fix switch language issue --- CHANGES.md | 1 + .../java/im/vector/app/VectorApplication.kt | 15 +++--- .../vector/app/core/services/VectorService.kt | 6 +++ .../configuration/VectorConfiguration.kt | 47 ++++++++++--------- .../VectorSettingsPreferencesFragment.kt | 1 + .../settings/locale/LocalePickerViewModel.kt | 5 +- .../vector/app/features/themes/ThemeUtils.kt | 6 +++ 7 files changed, 52 insertions(+), 29 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d3a16c9b29..1bde8a7dfd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Display name not shown under Settings/General (#1926) + - Fix changing language issue Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index 303b9d585a..f64ebf9245 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -32,10 +32,6 @@ import com.airbnb.epoxy.EpoxyAsyncUtil import com.airbnb.epoxy.EpoxyController import com.facebook.stetho.Stetho import com.gabrielittner.threetenbp.LazyThreeTen -import org.matrix.android.sdk.api.Matrix -import org.matrix.android.sdk.api.MatrixConfiguration -import org.matrix.android.sdk.api.auth.AuthenticationService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.DaggerVectorComponent import im.vector.app.core.di.HasVectorInjector @@ -50,16 +46,21 @@ import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.pin.PinLocker import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler +import im.vector.app.features.settings.VectorLocale import im.vector.app.features.settings.VectorPreferences +import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.version.VersionProvider import im.vector.app.push.fcm.FcmHelper +import org.matrix.android.sdk.api.Matrix +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.auth.AuthenticationService +import org.matrix.android.sdk.api.legacy.LegacySessionImporter import timber.log.Timber import java.text.SimpleDateFormat import java.util.Date import java.util.Locale import java.util.concurrent.Executors import javax.inject.Inject - import androidx.work.Configuration as WorkConfiguration class VectorApplication : @@ -119,7 +120,9 @@ class VectorApplication : R.array.com_google_android_gms_fonts_certs ) FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler()) - vectorConfiguration.initConfiguration() + VectorLocale.init(this) + ThemeUtils.init(this) + vectorConfiguration.applyToApplicationContext() emojiCompatWrapper.init(fontRequest) diff --git a/vector/src/main/java/im/vector/app/core/services/VectorService.kt b/vector/src/main/java/im/vector/app/core/services/VectorService.kt index 888f7a8cac..223d720d8a 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorService.kt @@ -17,8 +17,10 @@ package im.vector.app.core.services import android.app.Service +import android.content.Context import android.content.Intent import android.os.IBinder +import im.vector.app.core.extensions.vectorComponent import timber.log.Timber /** @@ -31,6 +33,10 @@ abstract class VectorService : Service() { */ private var mIsSelfDestroyed = false + override fun attachBaseContext(base: Context) { + super.attachBaseContext(vectorComponent().vectorConfiguration().getLocalisedContext(base)) + } + override fun onCreate() { super.onCreate() diff --git a/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt b/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt index 5567a138de..394eca030b 100644 --- a/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt +++ b/vector/src/main/java/im/vector/app/features/configuration/VectorConfiguration.kt @@ -16,10 +16,11 @@ package im.vector.app.features.configuration -import android.annotation.SuppressLint import android.content.Context import android.content.res.Configuration import android.os.Build +import android.os.LocaleList +import androidx.annotation.RequiresApi import im.vector.app.features.settings.FontScale import im.vector.app.features.settings.VectorLocale import im.vector.app.features.themes.ThemeUtils @@ -40,14 +41,9 @@ class VectorConfiguration @Inject constructor(private val context: Context) { } } - /** - * Init the configuration from the saved one - */ - fun initConfiguration() { - VectorLocale.init(context) + fun applyToApplicationContext() { val locale = VectorLocale.applicationLocale val fontScale = FontScale.getFontScaleValue(context) - val theme = ThemeUtils.getApplicationTheme(context) Locale.setDefault(locale) val config = Configuration(context.resources.configuration) @@ -56,9 +52,6 @@ class VectorConfiguration @Inject constructor(private val context: Context) { config.fontScale = fontScale.scale @Suppress("DEPRECATION") context.resources.updateConfiguration(config, context.resources.displayMetrics) - - // init the theme - ThemeUtils.setApplicationTheme(context, theme) } /** @@ -67,26 +60,22 @@ class VectorConfiguration @Inject constructor(private val context: Context) { * @param context the context * @return the localised context */ - @SuppressLint("NewApi") fun getLocalisedContext(context: Context): Context { try { - val resources = context.resources val locale = VectorLocale.applicationLocale - val configuration = resources.configuration + + // create new configuration passing old configuration from original Context + val configuration = Configuration(context.resources.configuration) + configuration.fontScale = FontScale.getFontScaleValue(context).scale if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - configuration.setLocale(locale) - configuration.setLayoutDirection(locale) - return context.createConfigurationContext(configuration) + setLocaleForApi24(configuration, locale) } else { - @Suppress("DEPRECATION") - configuration.locale = locale - configuration.setLayoutDirection(locale) - @Suppress("DEPRECATION") - resources.updateConfiguration(configuration, resources.displayMetrics) - return context + configuration.setLocale(locale) } + configuration.setLayoutDirection(locale) + return context.createConfigurationContext(configuration) } catch (e: Exception) { Timber.e(e, "## getLocalisedContext() failed") } @@ -94,6 +83,20 @@ class VectorConfiguration @Inject constructor(private val context: Context) { return context } + @RequiresApi(Build.VERSION_CODES.N) + private fun setLocaleForApi24(config: Configuration, locale: Locale) { + val set: MutableSet = LinkedHashSet() + // bring the user locale to the front of the list + set.add(locale) + val all = LocaleList.getDefault() + for (i in 0 until all.size()) { + // append other locales supported by the user + set.add(all[i]) + } + val locales = set.toTypedArray() + config.setLocales(LocaleList(*locales)) + } + /** * Compute the locale status value * @return the local status value diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt index 0d29137289..a84a10f74c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt @@ -168,6 +168,7 @@ class VectorSettingsPreferencesFragment @Inject constructor( v.setOnClickListener { dialog.dismiss() FontScale.updateFontScale(activity, i) + vectorConfiguration.applyToApplicationContext() activity.restart() } } diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt index fd20007c99..df7cc4ba84 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt @@ -26,11 +26,13 @@ import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.configuration.VectorConfiguration import im.vector.app.features.settings.VectorLocale import kotlinx.coroutines.launch class LocalePickerViewModel @AssistedInject constructor( - @Assisted initialState: LocalePickerViewState + @Assisted initialState: LocalePickerViewState, + private val vectorConfiguration: VectorConfiguration ) : VectorViewModel(initialState) { @AssistedInject.Factory @@ -70,6 +72,7 @@ class LocalePickerViewModel @AssistedInject constructor( private fun handleSelectLocale(action: LocalePickerAction.SelectLocale) { VectorLocale.saveApplicationLocale(action.locale) + vectorConfiguration.applyToApplicationContext() _viewEvents.post(LocalePickerViewEvents.RestartActivity) } } diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index ef806b55b4..d337b790a3 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -44,6 +44,12 @@ object ThemeUtils { private val mColorByAttr = HashMap() + // init the theme + fun init(context: Context) { + val theme = getApplicationTheme(context) + setApplicationTheme(context, theme) + } + /** * @return true if current theme is Light or Status */ From cb7a1bc9c302752d73237fb91a083adcfa7e6a6b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 24 Aug 2020 18:20:09 +0200 Subject: [PATCH 037/257] Fix FontSize issue (#1483, #1787) --- CHANGES.md | 1 + .../app/core/platform/VectorBaseActivity.kt | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1bde8a7dfd..ca35023ede 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Improvements 🙌: Bugfix 🐛: - Display name not shown under Settings/General (#1926) - Fix changing language issue + - Fix FontSize issue (#1483, #1787) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 856e84ea14..bedb02949f 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -76,6 +76,7 @@ import im.vector.app.features.rageshake.BugReportActivity import im.vector.app.features.rageshake.BugReporter import im.vector.app.features.rageshake.RageShake import im.vector.app.features.session.SessionListener +import im.vector.app.features.settings.FontScale import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.themes.ThemeUtils @@ -219,6 +220,9 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { doBeforeSetContentView() + // Hack for font size + applyFontSize() + if (getLayoutRes() != -1) { setContentView(getLayoutRes()) } @@ -239,6 +243,16 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { } } + /** + * This method has to be called for the font size setting be supported correctly. + */ + private fun applyFontSize() { + resources.configuration.fontScale = FontScale.getFontScaleValue(this).scale + + @Suppress("DEPRECATION") + resources.updateConfiguration(resources.configuration, resources.displayMetrics) + } + private fun handleGlobalError(globalError: GlobalError) { when (globalError) { is GlobalError.InvalidToken -> @@ -302,10 +316,10 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { super.onActivityResult(requestCode, resultCode, data) if (requestCode == PinActivity.PIN_REQUEST_CODE) { when (resultCode) { - Activity.RESULT_OK -> { + Activity.RESULT_OK -> { pinLocker.unlock() } - else -> { + else -> { pinLocker.block() moveTaskToBack(true) } From ee7f79b40c0a573b202bb318beea14cb89cb1db8 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 22 Aug 2020 18:42:52 +0000 Subject: [PATCH 038/257] Translated using Weblate (Bulgarian) Currently translated at 72.3% (170 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/bg/ --- .../src/main/res/values-bg/strings.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/res/values-bg/strings.xml b/matrix-sdk-android/src/main/res/values-bg/strings.xml index 07d59852f3..ad624eea41 100644 --- a/matrix-sdk-android/src/main/res/values-bg/strings.xml +++ b/matrix-sdk-android/src/main/res/values-bg/strings.xml @@ -204,4 +204,16 @@ %s изпрати запитване за потвърждение на ключа ви, но клиентът ви не поддържа верифициране посредством чат. Ще трябва да използвате стария метод за верифициране на ключове. %1$s създаде стаята - +Изпратихте снимка. + Изпратихте стикер. + + Ваша покана + Създадохте стаята + Поканихте %1$s + Присъединихте се в стаята + Напуснахте стаята + Отхвърлихте поканата + Изгонихте %1$s + Отблокирахте %1$s + Блокирахте %1$s + From 82c8b532c05967f6274ca5140897f736ddf3df7b Mon Sep 17 00:00:00 2001 From: linsui Date: Mon, 24 Aug 2020 10:23:12 +0000 Subject: [PATCH 039/257] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/zh_Hans/ --- vector/src/main/res/values-zh-rCN/strings.xml | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index cac1d7bd0e..11aaa448d5 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -179,7 +179,7 @@ 发送者的会话信息 公开名称 - ID + 会话 ID 会话密钥 验证 Ed25519 指纹 @@ -1794,7 +1794,7 @@ Element 在后台时的工作将被显著的限制,这可能会影响消息通 报告此内容 报告此内容的理由 报告 - 屏蔽用户 + 忽略用户 内容已报告 此内容已报告。 @@ -1815,7 +1815,7 @@ Element 在后台时的工作将被显著的限制,这可能会影响消息通 目前没有网络连接 - 屏蔽用户 + 忽略用户 全部消息(嘈杂) 全部消息 @@ -2532,4 +2532,31 @@ Element 在后台时的工作将被显著的限制,这可能会影响消息通 确认 PIN 并禁用 PIN 防止意外通话 发起通话之前要求确认 - +您没有权限在此聊天室发起会议通话 + 会议正在进行! + 发起视频会议 + 发起音频会议 + 会议使用 Jitsi 安全与许可政策。您的会议进行期间当前聊天室内的所有人将看到加入邀请。 + 您无法呼叫您自己 + 您无法呼叫您自己,请等待参与者接受邀请 + 添加小部件失败 + 移除小部件失败 + + 成功导入 %1$d/%2$d 个密钥。 + + + 管理集成 + 无活动小部件 + 聊天室已创建,但由于以下原因一些邀请尚未发送: +\n +\n%s + + + %1$s,%2$s 和其他 %3$d 人已读 + + + 错误代码,剩余 %d 次尝试 + + 注意!登出前最后一次尝试! + 错误次数过多,您已被登出 + From 01cfa4496c753930e35c72ea810f179f59ac6d95 Mon Sep 17 00:00:00 2001 From: aWeinzierl Date: Sat, 22 Aug 2020 15:49:29 +0000 Subject: [PATCH 040/257] Translated using Weblate (German) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 3ece35d4f8..9c3ae530ae 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -785,7 +785,7 @@ Achtung: Diese Datei wird vielleicht gelöscht, wenn die App deinstalliert wird. Vibriere beim Erwähnen eines Nutzers Benachrichtigungen - Dieser Raum zeigt für keine Communities die Abzeichen an + Dieser Raum zeigt für keine Community Avatare an Neue Community-ID (z.B. +foo:matrix.org) Ungültige Community-ID \'%s\' ist keine valide Community-ID @@ -819,7 +819,7 @@ Achtung: Diese Datei wird vielleicht gelöscht, wenn die App deinstalliert wird. Raum vergessen Startbildschirm-Verknüpfung hinzufügen - Abzeichen + Community Avatare Schüttele, um einen Fehler zu melden @@ -1763,7 +1763,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Diesen Inhalt melden Meldegrund MELDEN - NUTZER BLOCKIEREN + NUTZER IGNORIEREN Inhalt gemeldet Dieser Inhalt wurde gemeldet. @@ -1784,7 +1784,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Aktuell besteht keine Netzwerkverbindung - Nutzer blockieren + Nutzer ignorieren Alle Nachrichten (laut) Alle Nachrichten @@ -1891,7 +1891,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Beginne zu Tippen um eine Reaktion zu finden. %1$s hat den Raum auf \"nur-einladen\" gestellt. - Es ist dein Gespräch. Besitze es. + Es ist deine Konversation. Mache sie dir zu eigen. Premium-Hosting für Organisationen Gib die Adresse des Modular Element oder Servers ein, den du verwenden möchtest Gibt die Adresse eines Servers oder eines Element ein, zu dem du dich verbinden möchtest @@ -2620,7 +2620,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Aktiviere PIN Wenn du deine PIN zurücksetzen möchtest, tippe \"PIN vergessen\" um dich abzumelden und sie anschließend zurückzusetzen. Bestätige PIN um die PIN zu deaktivieren - Übertragung von Schlüsseln zur Entschlüsselung in Nachrichtenverlauf fehlgeschlagen + Fasse \"unable to decrypt\"-Fehler im Chatverlauf zu Hinweisen zusammen Verhindern Sie versehentliche Anrufe Bitten Sie um Bestätigung, bevor Sie einen Anruf tätigen Konfiguration @@ -2644,4 +2644,14 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine \n \n%s + + Von %1$s, %2$s und %3$d anderem gelesen + Von %1$s, %2$s und %3$d anderen gelesen + + + Falscher code, %d verbleibender Versuch + Falscher code, %d verbleibende Versuche + + Warnung! Letzter Versuch bevor du ausgeloggt wirst! + Zu viele Fehler, du bist ausgeloggt worden From f45d0122b07e3dacde2b3e768bb057d0c693140a Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Sat, 22 Aug 2020 17:29:05 +0000 Subject: [PATCH 041/257] Translated using Weblate (German) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/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 9c3ae530ae..e4ad8c52ee 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -1623,7 +1623,7 @@ Verwahre deinen Wiederherstellungsschlüssel an einem sehr sicheren Ort wie eine Bevorzugtes Synchronisationsintervall - Fund + Auffindbarkeit Öffentlicher Name (sichtbar für Personen, mit denen du kommunizierst) Der öffentliche Name der Sitzung ist für Personen sichtbar, mit denen du kommunizierst Um fortzufahren, musst du die Nutzungsbedingungen akzeptieren. From fd5e4b78da8d4201004fd5ee0404ba3d1c15ce94 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 17:37:04 +0000 Subject: [PATCH 042/257] Translated using Weblate (Kabyle) Currently translated at 24.6% (454 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/kab/ --- vector/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index 7d6d1b9033..03460b8e41 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -531,4 +531,6 @@ Timerniwt n uwiǧit ur teddi ara Izen yettwawgelhen + Imi xuṣṣent tsirag, izmer ur ttilint ara kra n tmahilin… + Tesriḍ tisirag akken ad tebduḍ asarag deg texxamt-a From 25d8ba2699a8ebaec1619ad840b020161f3c0b88 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 15:46:17 +0000 Subject: [PATCH 043/257] Translated using Weblate (Kabyle) Currently translated at 99.1% (233 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- .../src/main/res/values-kab/strings.xml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index 766b670d26..d8643bd425 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -72,13 +72,13 @@ Sekkeṛ Tasarut Tafḍist - Tiliγri + Tiliɣri Anay Tamacint Azlalam Timeẓdit Balles - Tagitaṛt + Tagiṭart Lɣiḍa Anayna Tamdeyt @@ -89,7 +89,7 @@ Qbel Agwi %1$s yuzen amenṭaḍ. - Tuzneḍ amenṭaḍ + Tuzneḍ amenṭaḍ. %1$s yekkes agdal i %2$s Tekkseḍ agdal i %1$s @@ -192,7 +192,7 @@ Akeṛmus - Tesremdeḍ awgelhen seg yixef ɣer yixef (alguritm arussin %1$s). + Tremdeḍ awgelhen seg yixef ɣer yixef (alguritm %1$s ur yettwassen ara). %s isuter-d ad isenqed tasarut-ik·im, maca amsaɣ-ik·im ur issefrak ara asenqed n tsura deg yidiwenniyen. Ilaq-ak·am useqdec asenqed iqdim n tsura i usenqed n tsura. @@ -282,4 +282,11 @@ %1$s yermed awgelhen seg yixef ɣer yixef. Tremdeḍ awgelhen seg yixef ɣer yixef. %1$s yermed awgelhen seg yixef ɣer yixef (alguritm %2$s ur yettwassen ara). + Tasarut + Tamessakt n lkaɣeḍ + Tarrazt + Sfeḍ tabdart n uraǧu n tuzzna + + %1$s issefsex tinubga n %2$s i tmerniwt ɣer texxamt. Tamentilt: %2$s + Tesfesxeḍ tinubga n %1$s i tmerna ɣer texxamt. Tamentilt: %2$s From 51893fff09674279991466f3971b515487eb9d89 Mon Sep 17 00:00:00 2001 From: ziriSut Date: Sun, 23 Aug 2020 15:47:52 +0000 Subject: [PATCH 044/257] Translated using Weblate (Kabyle) Currently translated at 99.1% (233 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/kab/ --- matrix-sdk-android/src/main/res/values-kab/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/res/values-kab/strings.xml b/matrix-sdk-android/src/main/res/values-kab/strings.xml index d8643bd425..c3afa2cbc2 100644 --- a/matrix-sdk-android/src/main/res/values-kab/strings.xml +++ b/matrix-sdk-android/src/main/res/values-kab/strings.xml @@ -289,4 +289,5 @@ %1$s issefsex tinubga n %2$s i tmerniwt ɣer texxamt. Tamentilt: %2$s Tesfesxeḍ tinubga n %1$s i tmerna ɣer texxamt. Tamentilt: %2$s + Yegguma ad yesfeḍ From 8e5656729bb7a935f63d82d0a67db3b90ffc291d Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sun, 23 Aug 2020 20:00:16 +0000 Subject: [PATCH 045/257] Translated using Weblate (Kabyle) Currently translated at 33.3% (1 of 3 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.riot.im/projects/element-android/element-store/kab/ --- vector/src/main/play/listings/kab/title.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 vector/src/main/play/listings/kab/title.txt diff --git a/vector/src/main/play/listings/kab/title.txt b/vector/src/main/play/listings/kab/title.txt new file mode 100644 index 0000000000..d854e8f975 --- /dev/null +++ b/vector/src/main/play/listings/kab/title.txt @@ -0,0 +1 @@ +Element (Riot.im zik) From 31b4785a4dbfd35b555b602ff5f0bddd56a49d63 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 22 Aug 2020 18:19:28 +0000 Subject: [PATCH 046/257] Translated using Weblate (Swedish) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 1000 ++++++++++++++++++++- 1 file changed, 988 insertions(+), 12 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 9fef0aa6b6..cbd5617c11 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -288,7 +288,7 @@ Förfrågan har skickats Vänligen öppna Element på en annan enhet som kan dekryptera meddelandet så att den kan skicka nycklarna till den här sessionen. - Läskvittolista + Läsindikationslista Grupplista @@ -566,7 +566,7 @@ Du kommer inte att verifiera %1$s (%2$s) om du avbryter nu. Börja igen i hens användarprofil. Meddelanden i det här rummet är totalsträckskrypterade. Lär dig mer och verifiera användare i deras profiler. - Visa alla meddelanden från den här användaren + Avignorera Är du säker på att du vill bjuda in %s till den här chatten\? Bjud in med ID Bjud in användare med ID @@ -646,7 +646,7 @@ Meddelanden innehållande mitt användarnamn Meddelanden i direktchattar Meddelanden i gruppchattar - Element kommer att synka I bakgrunden periodiskt vid precisa tider (konfigurerbart). + Element kommer att synka i bakgrunden periodiskt vid precisa tider (konfigurerbart). \nDetta kommer att påverka data- och batterianvändning, och det kommer att visas en permanent avisering som säger att Element lyssnar efter händelser. Version olm-version @@ -969,8 +969,8 @@ Normal Integrationer - Använd en integrationshanterare för att hantera bottar, bryggor, widgets och klistermärkespaket. -\nIntegrationshanterare får konfigurationsdata, och kan ändra widgets, skicka rumsinbjudningar, och ändra användarnivåer å dina vägnar. + Använd en integrationshanterare för att hantera bottar, bryggor, widgets och klistermärkespaket. +\nIntegrationshanterare får konfigurationsdata, och kan ändra widgets, skicka rumsinbjudningar, och ändra behörighetsnivåer å dina vägnar. Skicka meddelande med retur Returtangenten på mjukvarutangentbordet kommer att skicka ett meddelande istället för att lägga till ett radslut @@ -1138,7 +1138,7 @@ Avbryt inbjudan Omnämn Visa sessionslista - Du kommer inte kunna ångra den här ändringen eftersom du befordrar användaren till samma användarnivå som dig själv. + Du kommer inte kunna ångra den här ändringen eftersom du befordrar användaren till samma behörighetsnivå som dig själv. \nÄr du säker\? Degradera dig själv\? @@ -1295,7 +1295,7 @@ Apparna behöver inte ansluta till hemservern i bakgrunden, det bör reducera batterianvändning Tänd skärmen i 3 sekunder Bakgrundssynkronisering - Bakgrundssynkroniseringsläge (experimentellt) + Bakgrundssynkläge (experimentellt) Optimerad för batteri Användarvillkor Meddelanden från tredje part @@ -1307,8 +1307,8 @@ Sessioner Låt andra användare se när du skriver. Markdownformatering - Visa läst-indikationer - Tryck på läst-indikationer för en detaljerad lista. + Visa läsindikationer + Tryck på läsindikationer för en detaljerad lista. Säker säkerhetskopiering Sätt upp säker säkerhetskopiering Återställ säker säkerhetskopiering @@ -1408,7 +1408,7 @@ Algoritm Att verifiera den här sessionen kommer att markera den som betrodd, och även markera din session som betrodd för den andra parten. - Verifiera den här sessionen genom att bekräfta att följande emoji visas på den andra partens skärm + Verifiera den här sessionen genom att bekräfta att följande emojier visas på den andra partens skärm Verifiera den här sessionen genom att bekräfta att följande nummer visas på den andra partens skärm Du har framgångsrikt verifierat den här sessionen. @@ -1527,7 +1527,7 @@ Spara den på ett USB-minne eller en säkerhetskopieringsenhet - Nästan där! Visar den andra enheten samma sköld\? + Nästan färdigt! Visar den andra enheten samma sköld\? Misslyckades att importera nycklar Aktivera korssignering @@ -1552,4 +1552,980 @@ Sätt upp Skriv in en hemlig fras endast du känner till, och generera en nyckel för säkerhetskopiering. - + Element kommer att synka i bakgrunden på ett sätt som sparar på enhetens begränsade resurser (batteri). +\nBeroende på din enhets resurser, så kan synkroniseringen bli uppskjuten av operativsystemet. + Optimerad för realtid + Ingen bakgrundssynk + Du kommer inte att bli aviserad om inkommande meddelanden när appen är i bakgrunden. + Misslyckades att uppdatera inställningarna. + + + Starta vid boot + Aktivera bakgrundssynk + Timeout för synkbegäran + Föredraget synkintervall + %s +\nSynkroniseringen kan skjutas upp beroende på resurserna (batteri) eller status för enheten (vila). + Fördröjning mellan varje synkronisering + sekund + sekunder + + Lokala kontakter + Kontaktbehörighet + Land för telefonbok + Hemskärm + Inbäddade URL-förhandsgranskningar + Förhandsgranska länkar i chatten om din hemserver stöder den här funktionen. + Visa tidpunkter i 12-timmarsformat + Inbjudningar, utsparkningar och bann påverkas inte. + Visa kontohändelser + Vibrera när en användare nämns + Hantera + Detta kommer att ersätta din nuvarande nyckel eller fras. + + Ge behörighet + Välj ett annat alternativ + + Bakgrundsanslutning + Ge behörighet + + Statistik + Skicka statistikdata + Element samlar in anonym statistik för att låta oss förbättra appen. + Vänligen aktivera statistik för att hjälpa oss att förbättra Element. + Ja, jag vill hjälpa till! + + Databesparingsläge + ID + Publikt namna + Uppdatera publikt namn + Senast sedd + %1$s @ %2$s + Autentisering + Skicka in + + Integrationshanterare + + Verifikation pågår + Det här telefonnumret används redan. + Lösenorden matchar inte + + Är du säker på att du vill ta bort %1$s %2$s\? + + Välj ett land + + Land + Vänligen välj ett land + Telefonnummer + Ogiltigt telefonnummer för det valda landet + Telefonverifiering + Vi har skickat ett SMS med en aktiveringskod. Vänligen skriv denna kod nedan. + Skriv en aktiveringskod + Fel vid validering av ditt telefonnummer + Kod + Ett fel inträffade vid verifiering av ditt telefonnummer. + Ytterligare info: %s + + Förvald komprimering + Välj + Välj + Spela slutarljud + + 3 dagar + 1 vecka + 1 månad + För alltid + + Rumsbild + Rumsnamn + Ämne + Rumsetikett + Märkt som: + + Favorit + Låg prioritet + Ingen + + Behörighet och synlighet + Lista det här rummet i rumskatalogen + Rumstillgång + Synlighet för rumshistorik + Vem kan läsa historiken\? + Vem kan komma åt det här rummet\? + + Vem som helst + Endast medlemmar (från när det här alternativet valdes) + Endast medlemmar (sen de bjöds in) + Endast medlemmar (sen de gick med) + + För att länka till ett rum så måste det ha en adress. + Vem som helst som har rummets adress, förutom gäster + Vem som helst som har rummets adress, inklusive gäster + + Bannade användare + + %d bannad användare + %d bannade användare + + + Rummets interna ID + Adresser + Du behöver logga ut för att kunna aktivera krypteringen. + Det här rummet har inga lokala adresser + Ny adress (t.ex. #foo:matrix.org) + + Nytt gemenskaps-ID (t.ex. +foo:matrix.org) + Ogiltigt gemenskaps-ID + \'%s\' är inte ett giltigt gemenskaps-ID + + + Ogiltigt aliasformat + \'%s\' är inte ett giltigt format för ett alias + Du kommer inte att ha någon huvudadress specificerad för det här rummet. + Huvudadressvarningar + + Sätt som huvudadress + Avsätt som huvudadress + Kopiera rums-ID + Kopiera rumsadress + + Kryptering är avaktiverat i det här rummet. + Aktivera kryptering +\n(varning: kan inte avaktiveras igen!) + + Katalog + Händelseinformation + Användar-ID + Curve25519-identitetsnyckel + Gjorde anspråk på Ed25519-fingeravtrycksynyckel + Avkrypteringsfel + + Publikt namn + Publikt namn + Verifiering + Ed25519-fingeravtryck + + Nycklar framgångsrikt importerade + + + %1$d/%2$d nyckel importerad framgångsrikt. + %1$d/%2$d nycklar importerade framgångsrikt. + + + Inte verifierad + Verifierad + Svartlistad + + okänd IP + ingen + + Verifiera + Avverifiera + Svartlista + Avsvartlista + + Om de inte matchar så kan kommunikationens säkerhet vara äventyrad. + Jag verifierar att nycklarna matchar + + Servern kan vara otillgänglig eller överbelastad + Hemserver-URL + Skriv här… + + %1$s i %2$s + Ny händelse + Rum + Nya meddelanden + Nya inbjudningar + Jag + ** Misslyckades att skicka - vänligen öppna rummet + %1$s: %2$s + %1$s: %2$s %3$s + + Sök efter historiska + + Du behöver behörighet för att hantera widgets i det här rummet + Widgetskapning har misslyckats + Skapa gruppsamtal med Jitsi + Är du säker på att du vill radera den här widgeten från det här rummet\? + + 1 aktiv widget + %d aktiva widgets + + VISA + Aktiva widgets + + + Widgets + Ladda widget + Den här widgeten lades till av: + Att använda den kan sätta kakor och dela data med %s: + Att använda den kan dela data med %s: + Misslyckades att ladda widgeten. +\n%s + Ladda om widget + Öppna i webbläsaren + Återkalla tillgång för mig + + Din avatar-URL + Ditt användar-ID + Widget-ID + Rums-ID + + + Tyvärr, gruppsamtal med Jitsi stöds inte på gamla enheter (enheter med Android äldre än 5.0) + Den här widgeten vill använda följande resurser: + Tillåt + Blockera alla + Använd mikrofonen + Kunde inte skapa widgeten. + Misslyckades att skicka begäran. + Behörighetsnivå måste vara ett positivt heltal. + Du är inte i det här rummet. + Du har inte behörighet att göra det i det här rummet. + Saknar room_id i begäran. + Saknar user_id i begäran. + Rummet %s är inte synligt. + En krävd parameter saknas. + En parameter är inte giltig. + Ingen integrationshanterare konfigurerad. + Hantera integrationer + Inga aktiva widgets + Skicka röstmeddelanden + För att fortsätta behöver du acceptera villkoren för den här tjänsten. + + Starta verifiering + Verifiera + Dela utan att verifiera + Dela + Nyckeldelningsbegäran + Ignorera begäran + Ignorera + + Varning! + Gruppsamtal är under utveckling och kanske inte är pålitligt. + + Kommandofel + Okänt kommando: %s + Visar handling + Bannar användaren med det angivna ID:t + Avbannar användaren med det angivna ID:t + Definiera behörighetsnivå för en användare + Avoppar användaren med det angivna ID:t + Bjuder in användaren med det angivna ID:t till det nuvarande rummet + Går med i rummet med det angivna aliaset + Sätt ett rumsämne + Sparkar ut användaren med det angivna ID:t + Ändrar ditt visningsnamn + För att fixa Matrixapphantering + + Skapa + Skapa gemenskap + Gemenskapsnamn + Exempel + Gemenskaps-ID + exempel + + Hem + Inga användare + + Gick med + Bjöd in + + 1 medlem + %d medlemmar + + + Gemenskapsadministratören har inte försett en lång beskrivning för den här gemenskapen. + + Du har blivit utsparkad från %1$s av %2$s + Du har blivit bannad från %1$s av %2$s + Orsak: %1$s + Gå med igen + Glöm rummet + + Läsindikationsavatar + Notisavatar + Avatar + + Granska nu + + Vänligen skriv in ett användarnamn. + Det här rummet har blivit ersatt och är inte längre tillgängligt + Samtalet fortsätter här + Det här rummet är en fortsättning av en annan konversation + Tryck här för att se äldre meddelanden + + Resursgränsen överskriden + Hemservern har överskridit en av sina resursbegränsningar så vissa användare kommer inte att kunna logga in. + Den här hemservern har överskridit en av sina resursbegränsningar. + + Den här hemservern har nått sin månatliga aktiva användargräns så vissa användare kommer inte att kunna logga in. + Den här hemservern har nått sin månatliga aktiva användargräns. + + Vänligen %s för att öka den här gränsen. + Vänligen %s för att fortsätta använda den här tjänsten. + + Din hemserver stöder inte fördröjd inladdning av rumsmedlemmar än. Försök igen senare. + + Tyvärr, ett fel inträffade + + expandera + kollapsa + + Visa infoarean + Alltid + För meddelanden och fel + Endast för fel + + %1$s: + %1$s: %2$s + +%d + %d+ + Skapa lösenfras + Bekräfta lösenfras + Skriv lösenfras + Lösenfrasen matchar inte + Vänligen skriv en lösenfras + Lösenfrasen är för svag + + Vänligen radera lösenfrasen om du vill att Element ska generera en återställningsnyckel. + Sätt lösenfras + Skapar säkerhetskopia + Framgång ! + Klar + Jag har gjort en kopia + Spara återställningnyckel + Dela + Återställningsnyckeln har sparats. + + En säkerhetskopia finns redan på din hemserver + Ersätt + Stoppa + + Vänligen gör en kopia + Dela återställningsnyckel med… + Genererar återställningsnyckel med hjälp av lösenfras, den här processen kan ta flera sekunder. + Återställningsnyckel + Oväntat fel + Säkerhetskopiering startad + Är du säker\? + Du kan förlora åtkomst till dina meddelanden om du loggar ut ur eller förlorar den här enheten. + + använd din återställningsnyckel + Kan du inte din återställningslösenfras så kan du %s. + + Skriv in återställningsnyckel + + Säkerhetskopian kunde inte avkrypteras med den här lösenfrasen: vänligen verifiera att du skrev in rätt lösenfras. + Nätverksfel: vänligen kolla din anslutning och försök igen. + + Återställer säkerhetskopia: + Räknar ut återställningsnyckel… + Laddar ner nycklar… + Importerar nycklar… + Låser upp historia + Vänligen skriv in en återställningsnyckel + Säkerhetskopia återställd %s ! + Misslyckades att få betroendeinfo för säkerhetskopian (%s). + + Raderar säkerhetskopia… + Kollar status för säkerhetskopian + Det var jag + + Säkerhetskopierar dina nycklar. Detta kan ta flera minuter… + + + + Säkerhetskopierar %d nyckel… + Säkerhetskopierar %d nycklar… + + + Signatur + + Autokomplettera serveralternativ + Element detekterade en anpassad serverkonfiguration för din användar-ID-domän \"%1$s\": +\n%2$s + Använd konfig + + Verifiera genom att jämföra en kort textsträng. + För maximal säkerhet så rekommenderar vi att du gör det här personligen eller med en annan pålitlig form av kommunikation. + Påbörja verifiering + Inkommande verifieringsbegäran + Du mottog en inkommande verifieringsbegäran. + Visa begäran + Väntar på att den andra parten ska bekräfta… + + Verifierad! + Jag förstår + + Dyker inget upp\? Inte alla klienter stöder interaktiv verifiering än. Använd legacyverifiering. + Använd legacyverifiering. + + Nyckelverifiering + Begäran avbruten + Verifieringen är avbruten. +\nAnledning: %s + + Verifieringsbegäran + Användaren avbröt verifieringen + Verifieringsprocessen timeade ut + Hashåtagandet matchade inte + SAS:en matchade inte + Nyckelmismatch + Användarmismatch + Okänt fel + + Det verkar som att du försöker ansluta till en annan hemserver. Vill du logga ut\? + + Redigera + Svara + + Försök igen + Gå med i ett rum för att börja använda appen. + Skickade en inbjudan till dig + Inbjuden av %s + + Välkommen hit! + Kom ikapp med olästa meddelanden här + Konversationer + Reaktioner + Acceptera + Gilla + Lägg till reaktion + Visa reaktioner + Reaktioner + + Händelsen raderades av användaren + Händelsen modererades av en rumsadministratör + Senast redigerad av %1$s vid %2$s + + + Felformaterad händelse, kan inte visa + Inget nätverk. Vänligen kolla din internetanslutning. + Ändra + Vänligen vänta… + Det här rummet kan inte förhandsgranskas + Förhandsgranskning av världsläsbara rum stöds inte än av Element + + Nytt rum + SKAPA + Rumsnamn + Publikt + Vem som helst kommer kunna gå med i det här rummet + Rumskatalog + Publicera det här rummet till rumskatalogen + Rummet har skapats, men vissa inbjudningar har inte skickats av följande anledning: +\n +\n%s + + Ett fel inträffade vi hämtning av betroendeinfo + Ett fel inträffade vid hämtning av nyckelsäkerhetskopia + + Du tittar redan på det här rummet! + + Snabbreaktioner + + Expert + Inga registrerade pushgateways + + app_id: + push_key: + app_display_name: + session_name: + Url: + Format: + + Registrera token + + Väntar… + Krypterar miniatyrbild… + Skickar miniatyrbild (%1$s / %2$s) + (redigerad) + + Inga redigeringar funna + + Länk kopierad till klippbordet + + Skapar rum… + Börja skriva för att få resultat + Går med i rummet… + + Visa redigeringshistoria + + Användarvillkor + Granska villkor + Läst vid + + + Väntar + + Verifikationskoden är felaktig. + + Det verkar som att servern tar för lång tid att svara. Detta kan orsakas av antingen dålig uppkoppling eller ett fel på servern. Vänligen försök igen senare. + + Skicka bilaga + + Öppna navigationslådan + Öppna rumskapningsmenyn + Stäng rumskapningsmenyn… + Stäng nyckelsäkerhetskopieringsbannern + Hoppa till botten + + %1$s, %2$s och %3$s läste + %1$s och %2$s läste + %s läste + + 1 användare läste + %d användare läste + + + Ett fel inträffade vid hämtning av bilagan. + Kunde inte hantera delningsdata + + %1$s vid %2$s + Det är skräppost + Det är olämpligt + Anpassad rapport… + Rapportera det här innehållet + Anledning till att rapportera detta innehåll + RAPPORTERA + IGNORERA ANVÄNDARE + + Innehåll rapporterat + Rapporterad som skräppost + Rapporterad som olämplig + Det finns ingen nätverksanslutning just nu + + Ignorera användare + + Inställningar + Lägg till i favoriter + Ta bort från favoriter + %1$s gjorde inga ändringar + Du gjorde inga ändringar + Spoiler + %1$s gjorde rummet publikt för alla som har länken. + Du gjorde rummet publikt för alla som har länken. + Du ändrade rummet till endast inbjudna. + Olästa meddelanden + + Det är din konversation. Äg det. + Håll konversationer privata med kryptering + Utöka och anpassa din upplevelse + Kom igång + + Välj en server + Premiumservervärd för organisationer + Fortsätt + Anslut till %1$s + Anslut till Element Matrix Services + Anslut till en annan server + Logga in på %1$s + Bli medlem + Logga in + Fortsätt med SSO + + Element Matrix Services-adress + Adress + Premiumservervärd för organisationer + Skriv in adressen för Modular Element eller servern du vill använda + Skriv in adressen för en server eller Element du vill ansluta till + Skriv in adressen för servern du vill använda + + Ett fel inträffade vid laddning av sidan: %1$s (%2$d) + Appen kan inte logga in på den här hemservern. Hemservern stöder följande inloggninstyp(er): %1$s. +\n +\nVill du logga in med en webbklient\? + Tyvärr, den här servern accepterar inte nya konton. + Appen kan inte skapa ett konto på den här hemservern. +\n +\nVill du registrera dig med en webbklient\? + + Nästa + Varning! + Fortsätt + + Kolla din inkorg + Tryck på länken för att bekräfta ditt nya lösenord. När du har följt länken det innehåller, klicka nedan. + Framgång! + Ditt lösenord har återställts. + Tillbaka till inloggning + + Varning + Ditt lösenord har inte ändrats än. +\n +\nVill du avbryta återställningsprocessen\? + + Nästa + + Sätt telefonnummer + Vänligen använd internationellt format. + Telefonnummer + Telefonnummer (valfritt) + Nästa + + Bekräfta telefonnummer + Vi skickade just en kod till %1$s. Skriv in den nedan för att bekräfta att det är du. + Skriv in kod + Skicka igen + Nästa + + Internationella telefonnummer måste börja med \'+\' + Telefonnumret verkar vara ogiltigt. Vänligen kolla det + + Logga in på %1$s + Användarnamn + Lösenord + Nästa + Det användarnamnet är upptaget + Varning + Ditt konto är inte skapat än. +\n +\nVill du avbryta registreringsprocessen\? + + Välj matrix.org + Välj Element Matrix Services + Välj en annan hemserver + Vänligen utför captchautmaningen + Acceptera villkoren för att fortsätta + + Den inskrivna koden är felaktig. Vänligen kolla den. + Utdaterad hemserver + + För många förfrågningar har skickats. Du kan försöka igen om %1$d sekund… + För många förfrågningar har skickats. Du kan försöka igen om %1$d sekunder… + + + Alternativt, om du redan har ett konto och du kan ditt Matrix-ID och ditt lösenord, så kan du använda den här metoden: + Logga in med ditt Matrix-ID + Logga in med ditt Matrix-ID + Matrix-ID + Om du inte kan ditt lösenord, gå tillbaka för att återställa det. + Det här är inte ett giltigt användar-ID. Förväntat format: \'@användare:hemserver.org\' + Sett av + + Du är utloggad + Logga in igen + + Du är utloggad + Logga in + Administratören för din hemserver (%1$s) har loggat ut dig ur ditt konto %2$s (%3$s). + Logga in + Lösenord + Rensa personlig information + Rensa all data + + Rensa data + Du kommer att bli av med åtkomsten till dina krypterade meddelanden om du inte loggar in igen för att återfå dina krypteringsnycklar. + Rensa data + Din matrix.to-länk var felformaterad + Beskrivningen är för kort + + Inledande synk… + + Skakning upptäckt! + Inställningar + Aktivera kryptering + Obetrodd inloggning + De matchar + De matchar inte + Verifiera den här användaren genom att bekräfta att följande unika emojier visas på hens skärm i samma ordning. + För maximal säkerhet, använd en annan pålitlig kommunikationsform eller gör detta personligen. + Kolla efter den gröna skölden för att försäkra dig om att en användare är betrodd. Lita på alla användare i ett rum för att försäkra dig om att rummet är säkert. + + Inte säker + Video. + Bild. + Väntar… + %s avbröt + Du avbröt + %s accepterade + Du accepterade + Verifikation skickad + Verifieringsbegäran + Verifiera manuellt + + Du + + Skanna deras kod + Kan inte skanna + Om ni inte träffas personligen, jämför emojier istället + + Verifiera genom att jämföra emojier + + Verifiera med emojier + Om du inte kan skanna koden ovan, verifiera genom att jämföra ett kort, unikt urval av emojier. + + QR-kodsbild + + Verifiera %s + Verifierade %s + Väntar på %s… + För extra säkerhet, verifiera %s genom att kolla en engångskod på båda era enheter. +\n +\nFör maximal säkerhet, gör detta personligen. + Säkerhet + Adminhandlingar + Lämnar rummet… + + Anpassad + Inbjudningar + Användare + + Administratör i %1$s + Moderator i %1$s + Standard i %1$s + Anpassad (%1$d) i %1$s + + Hoppa till läsindikation + + Element hanterar inte händelser av typen \'%1$s\' + Element stötte på ett fel vid rendering av innehållet i händelsen med id \'%1$s\' + + Avignorera + + Skickar den givna emoten i regnbågsfärg + + Aktivera kryptering\? + Aktivera kryptering + + För att vara säker, verifiera %s genom att kolla en engångskod. + För att vara säker, gör detta personligen eller använd en annan säker kommunikationsform. + + Jämför de unika emojierna, och försäkra dig om att de visas i samma ordning. + Din serveradministratör har inaktiverat totalsträckskryptering som förval för privata rum och direktmeddelanden. + Ingen kryptografisk information tillgänglig + + Verifiera den här inloggningen + Fullborda säkerhet + + Verifiera + Verifierad + Varning + + Betrodd + Inte betrodd + + Initierar korssignering + Återställ nycklar + + QR-kod + + Nästan färdigt! Ser %s samma sköld\? + Ja + Nej + + Anslutningen till servern har tappats + Flygplansläge är på + + + %d röst + %d röster + + + %d röst - Slutgiltigt resultat + %d röster - Slutgiltigt resultat + + Valt alternativ + Skapar en enkel omröstning + Använd en återställningslösenfras eller -nyckel + Ny inloggning + + Skriv in en lösenfras för hemlig lagring + Varning: + Du bör endast komma åt hemlig lagring från en betrodd enhet + + Ta bort… + Vill du skicka den här bilagan till %1$s\? + + Skicka bild i originalstorlek + Skicka bilder i originalstorlek + + + Bekräfta borttagning + Är du säker på att du vill ta bort (radera) den här händelsen\? Observera att om du raderar ett rumsnamn eller ämnesändring så kan det upphäva ändringen. + Inkludera en anledning + Anledning för borttagning + + Händelsen raderades av användaren, anledning: %1$s + Händelsen modererades av rumsadministratören. Anledning: %1$s + + Nycklarna är redan uppdaterade! + + Element Android + + Ladda om + + Ny inloggning. Var det du\? + Tryck för att granska och verifiera + Det var inte jag + Ditt konto kan vara äventyrat + + Verifiera dina enheter i inställningarna. + Verifikation avbruten + + återställningslösenfras + kontolösenord + + Sätt en %s + Bekräfta %s + + Skriv in ditt %s för att fortsätta. + + Skriv in din %s igen för att fortsätta. + Använd inte ditt kontolösenord. + + Skriv in en säkerhetsfras endast du känner till, vilken används för att säkra hemligheter på din server. + + Detta kan ta flera sekunder, ha tålamod. + Sätter upp återställning. + Din återställningsnyckel + Du är färdig! + Håll den säker + Slutför + + Använd denna %1$s som ett skyddsnät ifall du glömmer din %2$s. + + Publicerar skapade identitetsnycklar + Genererar säkra nycklar baserat på lösenfras + Definierar förvald nyckel för SSSS + Synkroniserar huvudnyckel + Synkroniserar användarnyckel + Synkroniseras självsigneringsnyckel + Skriv ut den och spara den någonstans säkert + Kopiera den till din personliga molnlagring + + Du kan inte göra det där på mobilen + + Krypteringen som används i det här rummet stöds inte + + %s skapade och konfigurerade rummet. + Du skapade och konfigurerade rummet. + + Nästan färdigt! Väntar på bekräftelse… + Väntar på %s… + + Felaktigt användarnamn och/eller lösenord. Lösenordet du skrev börjar eller slutar med mellanslag, vänligen kolla det. + Kontot har inaktiverats. + + Krypteringsuppgradering tillgänglig + Verifiera dig själv och andra för att hålla dina chattar säkra + + Skriv in din %s för att fortsätta + Skriv in %s + Återställningslösenfras + Det är inte en giltig återställningsnyckel + Vänligen skriv in en återställningsnyckel + + Hämtar kurvnyckel + Generar SSSS-nyckel baserat på lösenfras + Generar SSSS-nyckel baserat på lösenfras (%s) + Generar SSSS-nyckel baserat på återställningsnyckel + Lagrar hemlighet för nyckelsäkerhetskopiering i SSSS + %1$s (%2$s) + + Element Webb +\nElement Skrivbord + Element iOS +\nElement Android + Använd din %1$s eller %2$s för att fortsätta. + Använd återställningsnyckel + Välj din återställningsnyckel eller mata in den manuellt genom att skriva den eller klistra in från klippbordet + Misslyckades att komma åt säker lagring + + Okrypterad + Krypterad av en overifierad enhet + Verifiera den nya inloggningen på ditt konto: %1$s + + Verifiera manuellt med text + Verifiera inloggning + Verifiera interaktivt med emojier + Markera som betrodd + + Vänligen välj ett användarnamn. + Vänligen välj att lösenord. + Dubbelkolla den här länken + Länken %1$s tar dig till en annan sida: %2$s. +\n +\nÄr du säker på att du vill fortsätta\? + + Lägg till medlemmar + Bjuder in användare… + Inbjudan skickad till %1$s + Inbjudan skickad till %1$s och %2$s + Öppna villkor för %s + Den här operationen är inte möjlig. Hemservern är utdaterad. + För ditt privatlivs skull stöder Element bara att skicka hashade e-postadresser och telefonnummer. + Associationen har misslyckats. + Det finns ingen nuvarande association med den här identifieraren. + + Använd %1$s + Skicka in + Sätt roll + Roll + Öppna chatt + Tysta mikrofonen + Sluta tysta mikrofonen + Använd säkerhetsnyckel + Generera en säkerhetsnyckel att lagra någonstans säkert, som en lösenordshanterare eller ett kassaskåp. + Använd en säkerhetsfras + Spara din säkerhetsnyckel + Spara din säkerhetsnyckel någonstans säkert, som en lösenordshanterare eller ett kassaskåp. + + Sätt an säkerhetsfras + Skriv in en säkerhetsfras endast du känner till, vilken används för att säkra hemligheter på din server. + Säkerhetsfras + Skriv in säkerhetsfrasen igen för att bekräfta den. + + Spara din säkerhetsnyckel + Spara din säkerhetsnyckel någonstans säkert, som en lösenordshanterare eller ett kassaskåp. + + Rumsnamn + Ämne + Du ändrade rumsinställningarna framgångsrikt + + Kan inte avkryptera + Väntar på krypteringshistorik + + Riot är nu Element! + Vi är glada att meddela att vi har bytt namn! Din app är uppdaterad och du är inloggad på ditt konto. + UPPFATTAT + LÄR DIG MER + + element + + + Spara återställningsnyckel i + + Lägg till från min telefonbok + Din telefonbok är tom + Telefonbok + Hämtar dina kontakter… + Kontaktbok + + Återkalla inbjudan + Återkalla inbjudan av %1$s\? + + Bannad av %1$s + Misslyckades att avbanna användaren + + Pushnotiser är inaktiverade + Granska dina inställningar för att aktivera pushnotiser + + Fel kod, %d försök kvar + Fel kod, %d försök kvar + + Varning! Sista försöket innan du loggas ut! + För många fel, du har blivit utloggad + Välj en PIN-kod för säkerhet + Bekräfta PIN + Misslyckades med att validera PIN, vänligen skriv en ny. + Skriv din PIN-kod + Glömt PIN\? + Återställ PIN + Ny PIN + För att återställa din PIN-kod behöver du logga in igen och skapa en ny. + Aktivera PIN + Om du vill återställa din PIN-kod, tryck på \"Glömt PIN\?\" för att logga ut och återställa. + Bekräfta PIN för att återställa PIN + From c1c8c045670b116b8e5e33d3238a6a09ba465376 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Aug 2020 12:31:55 +0200 Subject: [PATCH 047/257] Room detail: Fix roomId not set up when activity is restored --- .../home/room/detail/RoomDetailActivity.kt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index aa608ef4ef..de82689303 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -77,16 +77,15 @@ class RoomDetailActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) waitingView = waiting_view + val roomDetailArgs: RoomDetailArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) { + RoomDetailArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!) + } else { + intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS) + } + if (roomDetailArgs == null) return + currentRoomId = roomDetailArgs.roomId + if (isFirstCreation()) { - val roomDetailArgs: RoomDetailArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) { - RoomDetailArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!) - } else { - intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS) - } - - if (roomDetailArgs == null) return - - currentRoomId = roomDetailArgs.roomId replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs) replaceFragment(R.id.roomDetailDrawerContainer, BreadcrumbsFragment::class.java) } From 8f1eff8782655c6009c99c9a539aed947e80bfde Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Aug 2020 12:35:35 +0200 Subject: [PATCH 048/257] Start reusing RoomPreview for joining room not joined --- .../features/navigation/DefaultNavigator.kt | 18 ++++++++----- .../app/features/navigation/Navigator.kt | 3 ++- .../features/permalink/PermalinkHandler.kt | 25 ++++++++++++++----- .../roompreview/RoomPreviewActivity.kt | 22 ++++++++++------ .../RoomPreviewNoPreviewFragment.kt | 8 +++--- 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 3da6a7257a..ea35bbc087 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -54,6 +54,7 @@ import im.vector.app.features.pin.PinMode import im.vector.app.features.roomdirectory.RoomDirectoryActivity import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity import im.vector.app.features.roomdirectory.roompreview.RoomPreviewActivity +import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import im.vector.app.features.roommemberprofile.RoomMemberProfileActivity import im.vector.app.features.roommemberprofile.RoomMemberProfileArgs import im.vector.app.features.roomprofile.RoomProfileActivity @@ -64,6 +65,7 @@ import im.vector.app.features.terms.ReviewTermsActivity import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.session.terms.TermsService @@ -156,12 +158,16 @@ class DefaultNavigator @Inject constructor( } } - override fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String?, buildTask: Boolean) { - if (context is VectorBaseActivity) { - context.notImplemented("Open not joined room") - } else { - context.toast(R.string.not_implemented) - } + override fun openNotJoinedRoom(context: Context, roomId: String, eventId: String?, roomSummary: RoomSummary?, buildTask: Boolean) { + val roomPreviewData = RoomPreviewData( + roomId = roomId, + eventId = eventId, + roomAlias = roomSummary?.canonicalAlias, + roomName = roomSummary?.displayName, + avatarUrl = roomSummary?.avatarUrl + ) + val intent = RoomPreviewActivity.newIntent(context, roomPreviewData) + context.startActivity(intent) } override fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean) { diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index ee64c5fc75..b26c2711c7 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -28,6 +28,7 @@ import im.vector.app.features.pin.PinMode import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.share.SharedData import im.vector.app.features.terms.ReviewTermsActivity +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.session.terms.TermsService @@ -50,7 +51,7 @@ interface Navigator { fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) - fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String? = null, buildTask: Boolean = false) + fun openNotJoinedRoom(context: Context, roomId: String, eventId: String? = null, roomSummary: RoomSummary?, buildTask: Boolean = false) fun openRoomPreview(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData) diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 87d114c01b..8ab716d01d 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -19,12 +19,15 @@ package im.vector.app.features.permalink import android.content.Context import android.net.Uri import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.utils.toast import im.vector.app.features.navigation.Navigator import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser +import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.rx.rx import javax.inject.Inject @@ -82,8 +85,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti private fun PermalinkData.RoomLink.getRoomId(): Single> { val session = activeSessionHolder.getSafeActiveSession() return if (isRoomAlias && session != null) { - // At the moment we are not fetching on the server as we don't handle not join room - session.rx().getRoomIdByAlias(roomIdOrAlias, false).subscribeOn(Schedulers.io()) + session.rx().getRoomIdByAlias(roomIdOrAlias, true).subscribeOn(Schedulers.io()) } else { Single.just(Optional.from(roomIdOrAlias)) } @@ -94,10 +96,21 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti */ private fun openRoom(context: Context, roomId: String?, eventId: String?, buildTask: Boolean) { val session = activeSessionHolder.getSafeActiveSession() ?: return - return if (roomId != null && session.getRoom(roomId) != null) { - navigator.openRoom(context, roomId, eventId, buildTask) - } else { - navigator.openNotJoinedRoom(context, roomId, eventId, buildTask) + if (roomId == null) { + context.toast("Couldn't get roomId in permalink data.") + return + } + val roomSummary = session.getRoomSummary(roomId) + return when { + roomSummary?.membership?.isActive().orFalse() -> { + navigator.openRoom(context, roomId, eventId, buildTask) + } + roomSummary?.membership != Membership.BAN -> { + navigator.openNotJoinedRoom(context, roomId, eventId, roomSummary, buildTask) + } + else -> { + context.toast("Can't open a room where you are banned from.") + } } } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index 0a25d93de2..9bf5646a99 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -24,20 +24,22 @@ import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import kotlinx.android.parcel.Parcelize import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.util.MatrixItem -import kotlinx.android.parcel.Parcelize @Parcelize data class RoomPreviewData( val roomId: String, - val roomName: String?, - val roomAlias: String?, - val topic: String?, - val worldReadable: Boolean, - val avatarUrl: String?, - val homeServer: String? + val eventId: String? = null, + val roomName: String? = null, + val roomAlias: String? = null, + val topic: String? = null, + val worldReadable: Boolean = false, + val avatarUrl: String? = null, + val homeServer: String? = null, + val buildTask: Boolean = false ) : Parcelable { val matrixItem: MatrixItem get() = MatrixItem.RoomItem(roomId, roomName ?: roomAlias, avatarUrl) @@ -48,6 +50,12 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { private const val ARG = "ARG" + fun newIntent(context: Context, roomPreviewData: RoomPreviewData): Intent { + return Intent(context, RoomPreviewActivity::class.java).apply { + putExtra(ARG, roomPreviewData) + } + } + fun getIntent(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData): Intent { return Intent(context, RoomPreviewActivity::class.java).apply { putExtra(ARG, RoomPreviewData( diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index 5d13d3d9fe..108c3bacf1 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -48,13 +48,15 @@ class RoomPreviewNoPreviewFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupToolbar(roomPreviewNoPreviewToolbar) + val titleText = roomPreviewData.roomName ?: roomPreviewData.roomAlias ?: roomPreviewData.roomId + // Toolbar avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewToolbarAvatar) - roomPreviewNoPreviewToolbarTitle.text = roomPreviewData.roomName ?: roomPreviewData.roomAlias + roomPreviewNoPreviewToolbarTitle.text = titleText // Screen avatarRenderer.render(roomPreviewData.matrixItem, roomPreviewNoPreviewAvatar) - roomPreviewNoPreviewName.text = roomPreviewData.roomName ?: roomPreviewData.roomAlias + roomPreviewNoPreviewName.text = titleText roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic) if (roomPreviewData.worldReadable) { @@ -98,7 +100,7 @@ class RoomPreviewNoPreviewFragment @Inject constructor( // Quit this screen requireActivity().finish() // Open room - navigator.openRoom(requireActivity(), roomPreviewData.roomId) + navigator.openRoom(requireActivity(), roomPreviewData.roomId, roomPreviewData.eventId, roomPreviewData.buildTask) } } } From ceae1f1ad888ab36481123e17c6d856f8ca1cdc5 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Tue, 25 Aug 2020 10:06:29 +0000 Subject: [PATCH 049/257] Translated using Weblate (Kabyle) Currently translated at 25.2% (466 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/kab/ --- vector/src/main/res/values-kab/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index 03460b8e41..a757fc265a 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -533,4 +533,16 @@ Imi xuṣṣent tsirag, izmer ur ttilint ara kra n tmahilin… Tesriḍ tisirag akken ad tebduḍ asarag deg texxamt-a + Imi llant tsirag i ixuṣṣen, tigawt-a ur tezmir ara ad tili. + Isiwlen isaragen ur ttwasefraken ara deg texxamin yettwawgelhen + Ɣas siwel kan + Ɣas azen kan + Tebɣiḍ s tidet ad teffɣeḍ\? + Asiwel aɣectan + Asiwel s tvidyut + Anadi amatu + Tiririt taruradt + Creḍ yettwaɣra + Nɣel deg \"ɣef ufus\" + Sizdeg ismawen n texxamin From 70fda1009b66cb6cff25892c7a10d6dac745ffa5 Mon Sep 17 00:00:00 2001 From: tctovsli Date: Mon, 24 Aug 2020 18:23:20 +0000 Subject: [PATCH 050/257] =?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 33.1% (612 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/nb_NO/ --- vector/src/main/res/values-nb-rNO/strings.xml | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-nb-rNO/strings.xml b/vector/src/main/res/values-nb-rNO/strings.xml index ab5b4e5c28..d2ab1a8d4f 100644 --- a/vector/src/main/res/values-nb-rNO/strings.xml +++ b/vector/src/main/res/values-nb-rNO/strings.xml @@ -345,7 +345,7 @@ Invitert av %s Reaksjoner - Like + Liker Reaksjoner Endre @@ -671,7 +671,7 @@ Kan ikke starte samtale Informasjon om Økten Konferansesamtaler er ikke støttet i enkrypterte rom - Ring likevel. + Ring likevel Send likevel Er du sikker på at vil logge ut\? Telefonsamtale @@ -729,4 +729,51 @@ 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\? - +Spill av + Pause + Avslå + + + Du har ikke rettigheter til å starte en konferansesamtale i dette rommet + Det pågår allerede en konferanse! + Start videomøte + Start lydmøte + Møter bruker sikkerhets- og tilgangsregler fra Jitsi. Alle i rommet vil kunne se en invitasjon til møtet mens det pågår. + Du kan ikke ringe deg selv + Du kan ikke ringe deg selv. Vent til inviterte deltakere godtar invitasjonen + Kunne ikke legge til utvidelse + Kunne ikke fjerne utvidelse + Kopier + Suksess + + Varsler + Oppringing feilet som følge av feilkonfigurert tjener + Prøv med %s + Ikke spør meg igjen + + Element samtale feilet + Velg lydenhet + Telefon + Høytaler + Hodesett + Trådløst hodesett + Bytt kamera + Foran + Bak + Slå HD av + Slå HD på + + Send filer + Send klistremerke + Ta bilde eller video + Du har ingen pakker med klistremerker slått på. +\n +\nLegge til noen nå\? + + fortsett med… + Dessverre, kunne ikke finne en passende ekstern applikasjon for å utføre denne handlingen. + + Logg på med single sign-on + E-post eller brukernavn + Brukernavn + From ed9e5904982e10ea424fdb953168a76f88809f52 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 24 Aug 2020 18:46:56 +0000 Subject: [PATCH 051/257] Translated using Weblate (Swedish) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index cbd5617c11..472c6cfe96 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -22,7 +22,7 @@ Historisk Buggrapport Gemenskapsdetaljer - Skicka ett klistermärke + Skicka en dekal Säkerhetskopiering av nycklar Använd nyckelsäkerhetskopiering Verifiera session @@ -195,13 +195,13 @@ Fråga mig inte igen Skicka filer - Skicka klistermärke + Skicka dekal Ta foto eller video Ta ett foto Ta en video - Du har för närvarande inga klistermärkespaket aktiva. -\n + Du har för närvarande inga dekalpaket aktiva. +\n \nLägg till några nu\? fortsätt med… @@ -435,7 +435,7 @@ Ta bort från det här rummet Banna Avbanna - Kasta ut + Kicka Återställ till vanlig användare Gör till moderator Gör till administratör @@ -969,7 +969,7 @@ Normal Integrationer - Använd en integrationshanterare för att hantera bottar, bryggor, widgets och klistermärkespaket. + Använd en integrationshanterare för att hantera bottar, bryggor, widgets och dekalpaket. \nIntegrationshanterare får konfigurationsdata, och kan ändra widgets, skicka rumsinbjudningar, och ändra behörighetsnivåer å dina vägnar. Skicka meddelande med retur Returtangenten på mjukvarutangentbordet kommer att skicka ett meddelande istället för att lägga till ett radslut @@ -1050,7 +1050,7 @@ Sammanfogaren misslyckades med att avkryptera ett meddelande i tidslinjen Lägg till med Matrix-ID Inga resultat hittade, använd \"Lägg till med Matrix-ID\" för att söka på servern. - Använd bottar, bryggor, widgets och klistermärkespaket + Använd bottar, bryggor, widgets och dekalpaket Ett textmeddelande har skickats till %s. Vänligen skriv in verifieringskoden det innehåller. Filen \'%1$s\' (%2$s) är för stor för att laddas upp. Gränsen är %3$s. @@ -1060,14 +1060,14 @@ Kamera Ljud Galleri - Klistermärke + Dekal Skickar det valda meddelandet som en spoiler Gå med miljontals användare gratis på den största publika servern Lägger till ¯\\_(ツ)_/¯ till början av ett textmeddelande Ljud Fil - Klistermärke + Dekal Element hanterar inte meddelanden av typen \'%1$s\' Skickar det valda meddelandet I regnbågsfärger @@ -1151,15 +1151,15 @@ Att avignorera den här användaren kommer att visa alla meddelanden från hen igen. Avbryt inbjudan Är du säker på att du vill avbryta inbjudan för den här användaren\? - Sparka ut användaren - Anledning för utsparkning + Kicka användaren + Anledning för kick att sparka ut användaren kommer att ta bort hen från det här rummet. \n \nFör att hindra hen från att gå med i rummet igen så bör du banna hen istället. Banna användaren Anledning för bann Avbanna användaren - Att banna användaren kommer att sparka ut hen från det här rummet och hindra hen från att gå med igen. + Att banna användaren kommer att kicka hen från det här rummet och hindra hen från att gå med igen. Att avbanna användaren kommer att låta hen gå med i rummet igen. Anledning From 558e11a3643c52ff8b4977f4427d9ebebfe7da3e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 16:01:34 +0200 Subject: [PATCH 052/257] Refactor: move Kind to its own file --- .../android/sdk/api/pushrules/Condition.kt | 21 ---------- .../matrix/android/sdk/api/pushrules/Kind.kt | 39 +++++++++++++++++++ .../sdk/api/pushrules/rest/PushCondition.kt | 13 ++++--- .../database/mapper/PushRulesMapper.kt | 10 ++--- .../room/notification/RoomPushRuleMapper.kt | 4 +- 5 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Kind.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt index 50c2f8505b..462807cb06 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt @@ -20,27 +20,6 @@ import org.matrix.android.sdk.api.session.events.model.Event abstract class Condition(val kind: Kind) { - enum class Kind(val value: String) { - EventMatch("event_match"), - ContainsDisplayName("contains_display_name"), - RoomMemberCount("room_member_count"), - SenderNotificationPermission("sender_notification_permission"), - Unrecognised(""); - - companion object { - - fun fromString(value: String): Kind { - return when (value) { - "event_match" -> EventMatch - "contains_display_name" -> ContainsDisplayName - "room_member_count" -> RoomMemberCount - "sender_notification_permission" -> SenderNotificationPermission - else -> Unrecognised - } - } - } - } - abstract fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean open fun technicalDescription(): String { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Kind.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Kind.kt new file mode 100644 index 0000000000..78f3a8a156 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Kind.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.pushrules + +enum class Kind(val value: String) { + EventMatch("event_match"), + ContainsDisplayName("contains_display_name"), + RoomMemberCount("room_member_count"), + SenderNotificationPermission("sender_notification_permission"), + Unrecognised(""); + + companion object { + + fun fromString(value: String): Kind { + return when (value) { + "event_match" -> EventMatch + "contains_display_name" -> ContainsDisplayName + "room_member_count" -> RoomMemberCount + "sender_notification_permission" -> SenderNotificationPermission + else -> Unrecognised + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt index 9469da3ea5..e16c1df314 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt @@ -21,6 +21,7 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.pushrules.Condition import org.matrix.android.sdk.api.pushrules.ContainsDisplayNameCondition import org.matrix.android.sdk.api.pushrules.EventMatchCondition +import org.matrix.android.sdk.api.pushrules.Kind import org.matrix.android.sdk.api.pushrules.RoomMemberCountCondition import org.matrix.android.sdk.api.pushrules.SenderNotificationPermissionCondition import timber.log.Timber @@ -59,8 +60,8 @@ data class PushCondition( ) { fun asExecutableCondition(): Condition? { - return when (Condition.Kind.fromString(kind)) { - Condition.Kind.EventMatch -> { + return when (Kind.fromString(kind)) { + Kind.EventMatch -> { if (key != null && pattern != null) { EventMatchCondition(key, pattern) } else { @@ -68,10 +69,10 @@ data class PushCondition( null } } - Condition.Kind.ContainsDisplayName -> { + Kind.ContainsDisplayName -> { ContainsDisplayNameCondition() } - Condition.Kind.RoomMemberCount -> { + Kind.RoomMemberCount -> { if (iz.isNullOrEmpty()) { Timber.e("Malformed ROOM_MEMBER_COUNT condition") null @@ -79,7 +80,7 @@ data class PushCondition( RoomMemberCountCondition(iz) } } - Condition.Kind.SenderNotificationPermission -> { + Kind.SenderNotificationPermission -> { if (key == null) { Timber.e("Malformed Sender Notification Permission condition") null @@ -87,7 +88,7 @@ data class PushCondition( SenderNotificationPermissionCondition(key) } } - Condition.Kind.Unrecognised -> { + Kind.Unrecognised -> { Timber.e("Unknown kind $kind") null } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PushRulesMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PushRulesMapper.kt index 90fc62f8f3..3bcc3d2ea7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PushRulesMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/PushRulesMapper.kt @@ -17,12 +17,12 @@ package org.matrix.android.sdk.internal.database.mapper import com.squareup.moshi.Types -import org.matrix.android.sdk.api.pushrules.Condition +import io.realm.RealmList +import org.matrix.android.sdk.api.pushrules.Kind import org.matrix.android.sdk.api.pushrules.rest.PushCondition import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.internal.database.model.PushRuleEntity import org.matrix.android.sdk.internal.di.MoshiProvider -import io.realm.RealmList import timber.log.Timber internal object PushRulesMapper { @@ -39,7 +39,7 @@ internal object PushRulesMapper { enabled = pushrule.enabled, ruleId = pushrule.ruleId, conditions = listOf( - PushCondition(Condition.Kind.EventMatch.value, "content.body", pushrule.pattern) + PushCondition(Kind.EventMatch.value, "content.body", pushrule.pattern) ) ) } @@ -60,7 +60,7 @@ internal object PushRulesMapper { enabled = pushrule.enabled, ruleId = pushrule.ruleId, conditions = listOf( - PushCondition(Condition.Kind.EventMatch.value, "room_id", pushrule.ruleId) + PushCondition(Kind.EventMatch.value, "room_id", pushrule.ruleId) ) ) } @@ -72,7 +72,7 @@ internal object PushRulesMapper { enabled = pushrule.enabled, ruleId = pushrule.ruleId, conditions = listOf( - PushCondition(Condition.Kind.EventMatch.value, "user_id", pushrule.ruleId) + PushCondition(Kind.EventMatch.value, "user_id", pushrule.ruleId) ) ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/RoomPushRuleMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/RoomPushRuleMapper.kt index 1a19a40602..86a9500339 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/RoomPushRuleMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/notification/RoomPushRuleMapper.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.session.room.notification import org.matrix.android.sdk.api.pushrules.Action -import org.matrix.android.sdk.api.pushrules.Condition +import org.matrix.android.sdk.api.pushrules.Kind import org.matrix.android.sdk.api.pushrules.RuleSetKey import org.matrix.android.sdk.api.pushrules.getActions import org.matrix.android.sdk.api.pushrules.rest.PushCondition @@ -59,7 +59,7 @@ internal fun RoomNotificationState.toRoomPushRule(roomId: String): RoomPushRule? } else -> { val condition = PushCondition( - kind = Condition.Kind.EventMatch.value, + kind = Kind.EventMatch.value, key = "room_id", pattern = roomId ) From 7b5c74f81cd717839cfc2012d920919285b1516d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 16:06:26 +0200 Subject: [PATCH 053/257] Refactor: Condition is now an interface --- .../org/matrix/android/sdk/api/pushrules/Condition.kt | 9 +++------ .../sdk/api/pushrules/ContainsDisplayNameCondition.kt | 6 ++---- .../android/sdk/api/pushrules/EventMatchCondition.kt | 6 ++---- .../sdk/api/pushrules/RoomMemberCountCondition.kt | 6 ++---- .../pushrules/SenderNotificationPermissionCondition.kt | 6 ++---- 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt index 462807cb06..3b1082ea0a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Condition.kt @@ -18,11 +18,8 @@ package org.matrix.android.sdk.api.pushrules import org.matrix.android.sdk.api.session.events.model.Event -abstract class Condition(val kind: Kind) { +interface Condition { + fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean - abstract fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean - - open fun technicalDescription(): String { - return "Kind: $kind" - } + fun technicalDescription(): String } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt index a836c24c4e..2d0f81e5ca 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt @@ -22,15 +22,13 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import timber.log.Timber -class ContainsDisplayNameCondition : Condition(Kind.ContainsDisplayName) { +class ContainsDisplayNameCondition : Condition { override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveContainsDisplayNameCondition(event, this) } - override fun technicalDescription(): String { - return "User is mentioned" - } + override fun technicalDescription() = "User is mentioned" fun isSatisfied(event: Event, displayName: String): Boolean { val message = when (event.type) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt index 5eed785899..5646f5e805 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt @@ -30,15 +30,13 @@ class EventMatchCondition( * be treated as having asterisks prepended and appended when testing the condition. */ val pattern: String -) : Condition(Kind.EventMatch) { +) : Condition { override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveEventMatchCondition(event, this) } - override fun technicalDescription(): String { - return "'$key' Matches '$pattern'" - } + override fun technicalDescription() = "'$key' Matches '$pattern'" fun isSatisfied(event: Event): Boolean { // TODO encrypted events? diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RoomMemberCountCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RoomMemberCountCondition.kt index f97636a7bd..ba36c54fb4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RoomMemberCountCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RoomMemberCountCondition.kt @@ -29,15 +29,13 @@ class RoomMemberCountCondition( * If no prefix is present, this parameter defaults to ==. */ val iz: String -) : Condition(Kind.RoomMemberCount) { +) : Condition { override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveRoomMemberCountCondition(event, this) } - override fun technicalDescription(): String { - return "Room member count is $iz" - } + override fun technicalDescription() = "Room member count is $iz" internal fun isSatisfied(event: Event, roomGetter: RoomGetter): Boolean { // sanity checks diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/SenderNotificationPermissionCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/SenderNotificationPermissionCondition.kt index a8d08e5458..aeb2f01c80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/SenderNotificationPermissionCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/SenderNotificationPermissionCondition.kt @@ -28,15 +28,13 @@ class SenderNotificationPermissionCondition( * type from the notifications object in the power level event content. */ val key: String -) : Condition(Kind.SenderNotificationPermission) { +) : Condition { override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveSenderNotificationPermissionCondition(event, this) } - override fun technicalDescription(): String { - return "User power level <$key>" - } + override fun technicalDescription() = "User power level <$key>" fun isSatisfied(event: Event, powerLevels: PowerLevelsContent): Boolean { val powerLevelsHelper = PowerLevelsHelper(powerLevels) From f5ea4fb6ac44f993eb49bced2d29cd3851e6ff65 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 16:15:42 +0200 Subject: [PATCH 054/257] Refactor: Extract method to dedicated files --- .../pushrules/ContainsDisplayNameCondition.kt | 29 +------------- .../sdk/api/pushrules/EventMatchCondition.kt | 27 ++----------- .../matrix/android/sdk/internal/util/Glob.kt | 38 +++++++++++++++++++ .../android/sdk/internal/util/StringUtils.kt | 22 +++++++++++ 4 files changed, 65 insertions(+), 51 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt index 2d0f81e5ca..72eda20679 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/ContainsDisplayNameCondition.kt @@ -20,7 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import timber.log.Timber +import org.matrix.android.sdk.internal.util.caseInsensitiveFind class ContainsDisplayNameCondition : Condition { @@ -43,31 +43,6 @@ class ContainsDisplayNameCondition : Condition { else -> null } ?: return false - return caseInsensitiveFind(displayName, message.body) - } - - companion object { - /** - * Returns whether a string contains an occurrence of another, as a standalone word, regardless of case. - * - * @param subString the string to search for - * @param longString the string to search in - * @return whether a match was found - */ - fun caseInsensitiveFind(subString: String, longString: String): Boolean { - // add sanity checks - if (subString.isEmpty() || longString.isEmpty()) { - return false - } - - try { - val regex = Regex("(\\W|^)" + Regex.escape(subString) + "(\\W|$)", RegexOption.IGNORE_CASE) - return regex.containsMatchIn(longString) - } catch (e: Exception) { - Timber.e(e, "## caseInsensitiveFind() : failed") - } - - return false - } + return message.body.caseInsensitiveFind(displayName) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt index 5646f5e805..a6e3836a7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt @@ -18,6 +18,8 @@ package org.matrix.android.sdk.api.pushrules import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.hasSpecialGlobChar +import org.matrix.android.sdk.internal.util.simpleGlobToRegExp import timber.log.Timber class EventMatchCondition( @@ -47,7 +49,7 @@ class EventMatchCondition( // Patterns with no special glob characters should be treated as having asterisks prepended // and appended when testing the condition. try { - val modPattern = if (hasSpecialGlobChar(pattern)) simpleGlobToRegExp(pattern) else simpleGlobToRegExp("*$pattern*") + val modPattern = if (pattern.hasSpecialGlobChar()) pattern.simpleGlobToRegExp() else "*$pattern*".simpleGlobToRegExp() val regex = Regex(modPattern, RegexOption.DOT_MATCHES_ALL) return regex.containsMatchIn(value) } catch (e: Throwable) { @@ -76,27 +78,4 @@ class EventMatchCondition( } return null } - - companion object { - - private fun hasSpecialGlobChar(glob: String): Boolean { - return glob.contains("*") || glob.contains("?") - } - - // Very simple glob to regexp converter - private fun simpleGlobToRegExp(glob: String): String { - var out = "" // "^" - for (element in glob) { - when (element) { - '*' -> out += ".*" - '?' -> out += '.'.toString() - '.' -> out += "\\." - '\\' -> out += "\\\\" - else -> out += element - } - } - out += "" // '$'.toString() - return out - } - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt new file mode 100644 index 0000000000..fb8a5367dd --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.util + +internal fun String.hasSpecialGlobChar(): Boolean { + return contains("*") || contains("?") +} + +// Very simple glob to regexp converter +internal fun String.simpleGlobToRegExp(): String { + var out = "" // "^" + for (element in this) { + when (element) { + '*' -> out += ".*" + '?' -> out += '.'.toString() + '.' -> out += "\\." + '\\' -> out += "\\\\" + else -> out += element + } + } + out += "" // '$'.toString() + return out +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt index a236771cd6..681e7e5fed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt @@ -52,3 +52,25 @@ fun convertFromUTF8(s: String): String { } fun String.withoutPrefix(prefix: String) = if (startsWith(prefix)) substringAfter(prefix) else this + +/** + * Returns whether a string contains an occurrence of another, as a standalone word, regardless of case. + * + * @param subString the string to search for + * @return whether a match was found + */ +fun String.caseInsensitiveFind(subString: String): Boolean { + // add sanity checks + if (subString.isEmpty() || isEmpty()) { + return false + } + + try { + val regex = Regex("(\\W|^)" + Regex.escape(subString) + "(\\W|$)", RegexOption.IGNORE_CASE) + return regex.containsMatchIn(this) + } catch (e: Exception) { + Timber.e(e, "## caseInsensitiveFind() : failed") + } + + return false +} From aca8fd7f3d80fde7784ee9086400599ef1003f91 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 16:18:44 +0200 Subject: [PATCH 055/257] Refactor: Kotlin style --- .../matrix/android/sdk/internal/util/Glob.kt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt index fb8a5367dd..129bf0dec4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Glob.kt @@ -23,16 +23,18 @@ internal fun String.hasSpecialGlobChar(): Boolean { // Very simple glob to regexp converter internal fun String.simpleGlobToRegExp(): String { - var out = "" // "^" - for (element in this) { - when (element) { - '*' -> out += ".*" - '?' -> out += '.'.toString() - '.' -> out += "\\." - '\\' -> out += "\\\\" - else -> out += element + val string = this + return buildString { + // append("^") + string.forEach { char -> + when (char) { + '*' -> append(".*") + '?' -> append(".") + '.' -> append("\\.") + '\\' -> append("\\\\") + else -> append(char) + } } + // append("$") } - out += "" // '$'.toString() - return out } From 0d9885a1e077705c0621f287cf408474a08e7490 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 16:53:12 +0200 Subject: [PATCH 056/257] Refactor: Remove duplicated declaration for RuleIds --- .../android/sdk/api/pushrules/RuleIds.kt | 2 ++ .../sdk/api/pushrules/rest/PushRule.kt | 19 ------------- .../android/sdk/api/pushrules/rest/RuleSet.kt | 3 +- .../app/core/preference/PushRulePreference.kt | 11 ++++---- ...sAdvancedNotificationPreferenceFragment.kt | 28 +++++++++---------- 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RuleIds.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RuleIds.kt index eeb2577d4c..2353d06252 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RuleIds.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/RuleIds.kt @@ -45,4 +45,6 @@ object RuleIds { // Not documented const val RULE_ID_FALLBACK = ".m.rule.fallback" + + const val RULE_ID_REACTION = ".m.rule.reaction" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt index 46d73a8aa2..24a16ba655 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt @@ -136,25 +136,6 @@ data class PushRule( fun shouldNotNotify() = actions.contains(ACTION_DONT_NOTIFY) companion object { - /* ========================================================================================== - * Rule id - * ========================================================================================== */ - - const val RULE_ID_DISABLE_ALL = ".m.rule.master" - const val RULE_ID_CONTAIN_USER_NAME = ".m.rule.contains_user_name" - const val RULE_ID_CONTAIN_DISPLAY_NAME = ".m.rule.contains_display_name" - const val RULE_ID_ONE_TO_ONE_ROOM = ".m.rule.room_one_to_one" - const val RULE_ID_INVITE_ME = ".m.rule.invite_for_me" - const val RULE_ID_PEOPLE_JOIN_LEAVE = ".m.rule.member_event" - const val RULE_ID_CALL = ".m.rule.call" - const val RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS = ".m.rule.suppress_notices" - const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message" - const val RULE_ID_AT_ROOMS = ".m.rule.roomnotif" - const val RULE_ID_TOMBSTONE = ".m.rule.tombstone" - const val RULE_ID_E2E_ONE_TO_ONE_ROOM = ".m.rule.encrypted_room_one_to_one" - const val RULE_ID_E2E_GROUP = ".m.rule.encrypted" - const val RULE_ID_REACTION = ".m.rule.reaction" - const val RULE_ID_FALLBACK = ".m.rule.fallback" /* ========================================================================================== * Actions diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/RuleSet.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/RuleSet.kt index eb813dba45..a8708819f5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/RuleSet.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/RuleSet.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.pushrules.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.RuleSetKey /** @@ -51,7 +52,7 @@ data class RuleSet( var result: PushRuleAndKind? = null // sanity check if (null != ruleId) { - if (PushRule.RULE_ID_CONTAIN_USER_NAME == ruleId) { + if (RuleIds.RULE_ID_CONTAIN_USER_NAME == ruleId) { result = findRule(content, ruleId)?.let { PushRuleAndKind(it, RuleSetKey.CONTENT) } } else { // assume that the ruleId is unique. diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt index 87584a9db0..c19a7e4def 100755 --- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt @@ -23,6 +23,7 @@ import android.widget.RadioGroup import android.widget.TextView import androidx.preference.PreferenceViewHolder import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.RuleSetKey import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind @@ -52,7 +53,7 @@ class PushRulePreference : VectorPreference { get() { val safeRule = ruleAndKind?.pushRule ?: return NOTIFICATION_OFF_INDEX - if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { if (safeRule.shouldNotNotify()) { return if (safeRule.enabled) { NOTIFICATION_OFF_INDEX @@ -109,7 +110,7 @@ class PushRulePreference : VectorPreference { val safeKind = ruleAndKind?.kind ?: return null return if (index != ruleStatusIndex) { - if (safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + if (safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { when (index) { NOTIFICATION_OFF_INDEX -> { safeRule.copy(enabled = true) @@ -129,7 +130,7 @@ class PushRulePreference : VectorPreference { } } else { if (NOTIFICATION_OFF_INDEX == index) { - if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { + if (safeKind == RuleSetKey.UNDERRIDE || safeRule.ruleId == RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS) { safeRule.setNotify(false) } else { safeRule.copy(enabled = false) @@ -138,12 +139,12 @@ class PushRulePreference : VectorPreference { val newRule = safeRule.copy(enabled = true) .setNotify(true) .setHighlight(safeKind != RuleSetKey.UNDERRIDE - && safeRule.ruleId != PushRule.RULE_ID_INVITE_ME + && safeRule.ruleId != RuleIds.RULE_ID_INVITE_ME && NOTIFICATION_NOISY_INDEX == index) if (NOTIFICATION_NOISY_INDEX == index) { newRule.setNotificationSound( - if (safeRule.ruleId == PushRule.RULE_ID_CALL) { + if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { PushRule.ACTION_VALUE_RING } else { PushRule.ACTION_VALUE_DEFAULT diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt index 27160ba234..67b5c03638 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsAdvancedNotificationPreferenceFragment.kt @@ -16,13 +16,13 @@ package im.vector.app.features.settings import androidx.preference.Preference -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.pushrules.rest.PushRule -import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind import im.vector.app.R import im.vector.app.core.preference.PushRulePreference import im.vector.app.core.preference.VectorPreference import im.vector.app.core.utils.toast +import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.pushrules.RuleIds +import org.matrix.android.sdk.api.pushrules.rest.PushRuleAndKind import javax.inject.Inject class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() @@ -92,17 +92,17 @@ class VectorSettingsAdvancedNotificationPreferenceFragment @Inject constructor() companion object { // preference name <-> rule Id private val prefKeyToPushRuleId = mapOf( - "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_DISPLAY_NAME, - "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to PushRule.RULE_ID_CONTAIN_USER_NAME, - "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to PushRule.RULE_ID_ONE_TO_ONE_ROOM, - "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, - "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to PushRule.RULE_ID_INVITE_ME, - "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to PushRule.RULE_ID_CALL, - "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to PushRule.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, - "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to PushRule.RULE_ID_AT_ROOMS, - "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_E2E_ONE_TO_ONE_ROOM, - "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to PushRule.RULE_ID_E2E_GROUP, - "SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to PushRule.RULE_ID_TOMBSTONE + "SETTINGS_PUSH_RULE_CONTAINING_MY_DISPLAY_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_DISPLAY_NAME, + "SETTINGS_PUSH_RULE_CONTAINING_MY_USER_NAME_PREFERENCE_KEY" to RuleIds.RULE_ID_CONTAIN_USER_NAME, + "SETTINGS_PUSH_RULE_MESSAGES_IN_ONE_TO_ONE_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ALL_OTHER_MESSAGES_ROOMS, + "SETTINGS_PUSH_RULE_INVITED_TO_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_INVITE_ME, + "SETTINGS_PUSH_RULE_CALL_INVITATIONS_PREFERENCE_KEY" to RuleIds.RULE_ID_CALL, + "SETTINGS_PUSH_RULE_MESSAGES_SENT_BY_BOT_PREFERENCE_KEY" to RuleIds.RULE_ID_SUPPRESS_BOTS_NOTIFICATIONS, + "SETTINGS_PUSH_RULE_MESSAGES_CONTAINING_AT_ROOM_PREFERENCE_KEY" to RuleIds.RULE_ID_ROOM_NOTIF, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_ONE_ONE_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM, + "SETTINGS_PUSH_RULE_MESSAGES_IN_E2E_GROUP_CHAT_PREFERENCE_KEY" to RuleIds.RULE_ID_ENCRYPTED, + "SETTINGS_PUSH_RULE_ROOMS_UPGRADED_KEY" to RuleIds.RULE_ID_TOMBSTONE ) } } From bf7a096a187af7721694b57be954fac8b66c97ef Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:01:55 +0200 Subject: [PATCH 057/257] Refactor: Remove duplicated declaration for Actions --- .../android/sdk/api/pushrules/Action.kt | 65 ++++++++++--------- .../sdk/api/pushrules/rest/PushRule.kt | 34 ++-------- .../fcm/VectorFirebaseMessagingService.kt | 8 +-- .../app/core/preference/PushRulePreference.kt | 5 +- 4 files changed, 48 insertions(+), 64 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Action.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Action.kt index 7a21920e58..ff58650781 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Action.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/Action.kt @@ -24,21 +24,24 @@ sealed class Action { object DoNotNotify : Action() data class Sound(val sound: String = ACTION_OBJECT_VALUE_VALUE_DEFAULT) : Action() data class Highlight(val highlight: Boolean) : Action() + + companion object { + const val ACTION_NOTIFY = "notify" + const val ACTION_DONT_NOTIFY = "dont_notify" + const val ACTION_COALESCE = "coalesce" + + // Ref: https://matrix.org/docs/spec/client_server/latest#tweaks + const val ACTION_OBJECT_SET_TWEAK_KEY = "set_tweak" + + const val ACTION_OBJECT_SET_TWEAK_VALUE_SOUND = "sound" + const val ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT = "highlight" + + const val ACTION_OBJECT_VALUE_KEY = "value" + const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default" + const val ACTION_OBJECT_VALUE_VALUE_RING = "ring" + } } -private const val ACTION_NOTIFY = "notify" -private const val ACTION_DONT_NOTIFY = "dont_notify" -private const val ACTION_COALESCE = "coalesce" - -// Ref: https://matrix.org/docs/spec/client_server/latest#tweaks -private const val ACTION_OBJECT_SET_TWEAK_KEY = "set_tweak" - -private const val ACTION_OBJECT_SET_TWEAK_VALUE_SOUND = "sound" -private const val ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT = "highlight" - -private const val ACTION_OBJECT_VALUE_KEY = "value" -private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default" - /** * Ref: https://matrix.org/docs/spec/client_server/latest#actions * @@ -69,18 +72,18 @@ private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default" fun List.toJson(): List { return map { action -> when (action) { - is Action.Notify -> ACTION_NOTIFY - is Action.DoNotNotify -> ACTION_DONT_NOTIFY - is Action.Sound -> { + is Action.Notify -> Action.ACTION_NOTIFY + is Action.DoNotNotify -> Action.ACTION_DONT_NOTIFY + is Action.Sound -> { mapOf( - ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_SOUND, - ACTION_OBJECT_VALUE_KEY to action.sound + Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND, + Action.ACTION_OBJECT_VALUE_KEY to action.sound ) } - is Action.Highlight -> { + is Action.Highlight -> { mapOf( - ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT, - ACTION_OBJECT_VALUE_KEY to action.highlight + Action.ACTION_OBJECT_SET_TWEAK_KEY to Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT, + Action.ACTION_OBJECT_VALUE_KEY to action.highlight ) } } @@ -92,26 +95,26 @@ fun PushRule.getActions(): List { actions.forEach { actionStrOrObj -> when (actionStrOrObj) { - ACTION_NOTIFY -> Action.Notify - ACTION_DONT_NOTIFY -> Action.DoNotNotify - is Map<*, *> -> { - when (actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]) { - ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> { - (actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue -> + Action.ACTION_NOTIFY -> Action.Notify + Action.ACTION_DONT_NOTIFY -> Action.DoNotNotify + is Map<*, *> -> { + when (actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]) { + Action.ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> { + (actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue -> Action.Sound(stringValue) } // When the value is not there, default sound (not specified by the spec) - ?: Action.Sound(ACTION_OBJECT_VALUE_VALUE_DEFAULT) + ?: Action.Sound(Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT) } - ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> { - (actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue -> + Action.ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> { + (actionStrOrObj[Action.ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue -> Action.Highlight(boolValue) } // When the value is not there, default is true, says the spec ?: Action.Highlight(true) } else -> { - Timber.w("Unsupported set_tweak value ${actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]}") + Timber.w("Unsupported set_tweak value ${actionStrOrObj[Action.ACTION_OBJECT_SET_TWEAK_KEY]}") null } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt index 24a16ba655..bdb4f2cf29 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushRule.kt @@ -63,7 +63,7 @@ data class PushRule( * Add the default notification sound. */ fun setNotificationSound(): PushRule { - return setNotificationSound(ACTION_VALUE_DEFAULT) + return setNotificationSound(Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT) } fun getNotificationSound(): String? { @@ -109,13 +109,13 @@ data class PushRule( fun setNotify(notify: Boolean): PushRule { val mutableActions = actions.toMutableList() - mutableActions.remove(ACTION_DONT_NOTIFY) - mutableActions.remove(ACTION_NOTIFY) + mutableActions.remove(Action.ACTION_DONT_NOTIFY) + mutableActions.remove(Action.ACTION_NOTIFY) if (notify) { - mutableActions.add(ACTION_NOTIFY) + mutableActions.add(Action.ACTION_NOTIFY) } else { - mutableActions.add(ACTION_DONT_NOTIFY) + mutableActions.add(Action.ACTION_DONT_NOTIFY) } return copy(actions = mutableActions) @@ -126,32 +126,12 @@ data class PushRule( * * @return true if the rule should play sound */ - fun shouldNotify() = actions.contains(ACTION_NOTIFY) + fun shouldNotify() = actions.contains(Action.ACTION_NOTIFY) /** * Return true if the rule should not highlight the event. * * @return true if the rule should not play sound */ - fun shouldNotNotify() = actions.contains(ACTION_DONT_NOTIFY) - - companion object { - - /* ========================================================================================== - * Actions - * ========================================================================================== */ - - const val ACTION_NOTIFY = "notify" - const val ACTION_DONT_NOTIFY = "dont_notify" - const val ACTION_COALESCE = "coalesce" - - const val ACTION_SET_TWEAK_SOUND_VALUE = "sound" - const val ACTION_SET_TWEAK_HIGHLIGHT_VALUE = "highlight" - - const val ACTION_PARAMETER_SET_TWEAK = "set_tweak" - const val ACTION_PARAMETER_VALUE = "value" - - const val ACTION_VALUE_DEFAULT = "default" - const val ACTION_VALUE_RING = "ring" - } + fun shouldNotNotify() = actions.contains(Action.ACTION_DONT_NOTIFY) } diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index 617e40225d..be0ce86326 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -25,9 +25,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.ProcessLifecycleOwner import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage -import org.matrix.android.sdk.api.pushrules.rest.PushRule -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.events.model.Event import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder @@ -40,6 +37,9 @@ import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.SimpleNotifiableEvent import im.vector.app.features.settings.VectorPreferences import im.vector.app.push.fcm.FcmHelper +import org.matrix.android.sdk.api.pushrules.Action +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.events.model.Event import timber.log.Timber /** @@ -196,7 +196,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { description = "", type = null, timestamp = System.currentTimeMillis(), - soundName = PushRule.ACTION_VALUE_DEFAULT, + soundName = Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT, isPushGatewayEvent = true ) notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent) diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt index c19a7e4def..0c9721e589 100755 --- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt @@ -23,6 +23,7 @@ import android.widget.RadioGroup import android.widget.TextView import androidx.preference.PreferenceViewHolder import im.vector.app.R +import org.matrix.android.sdk.api.pushrules.Action import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.RuleSetKey import org.matrix.android.sdk.api.pushrules.rest.PushRule @@ -145,9 +146,9 @@ class PushRulePreference : VectorPreference { if (NOTIFICATION_NOISY_INDEX == index) { newRule.setNotificationSound( if (safeRule.ruleId == RuleIds.RULE_ID_CALL) { - PushRule.ACTION_VALUE_RING + Action.ACTION_OBJECT_VALUE_VALUE_RING } else { - PushRule.ACTION_VALUE_DEFAULT + Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT } ) } else { From 2e618999d9ff481c89920b69e23169c56efaf046 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:26:16 +0200 Subject: [PATCH 058/257] Words containing my name should not trigger notifications (Fixes #1781) It adds a specific behavior for rule with id RuleIds.RULE_ID_CONTAIN_USER_NAME --- CHANGES.md | 1 + .../sdk/api/pushrules/EventMatchCondition.kt | 23 ++++++++---- .../sdk/api/pushrules/rest/PushCondition.kt | 5 ++- .../notification/ProcessEventForPushTask.kt | 2 +- .../api/pushrules/PushrulesConditionTest.kt | 37 +++++++++++++------ .../features/settings/push/PushRuleItem.kt | 6 +-- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d3a16c9b29..2ab1214b36 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Display name not shown under Settings/General (#1926) + - Words containing my name should not trigger notifications (#1781) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt index a6e3836a7a..c10d2fc1df 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.pushrules import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.caseInsensitiveFind import org.matrix.android.sdk.internal.util.hasSpecialGlobChar import org.matrix.android.sdk.internal.util.simpleGlobToRegExp import timber.log.Timber @@ -31,14 +32,18 @@ class EventMatchCondition( * The glob-style pattern to match against. Patterns with no special glob characters should * be treated as having asterisks prepended and appended when testing the condition. */ - val pattern: String + val pattern: String, + /** + * true to match only words. In this case pattern will not be considered as a glob + */ + val wordsOnly: Boolean ) : Condition { override fun isSatisfied(event: Event, conditionResolver: ConditionResolver): Boolean { return conditionResolver.resolveEventMatchCondition(event, this) } - override fun technicalDescription() = "'$key' Matches '$pattern'" + override fun technicalDescription() = "'$key' Matches '$pattern', words only '$wordsOnly'" fun isSatisfied(event: Event): Boolean { // TODO encrypted events? @@ -48,14 +53,18 @@ class EventMatchCondition( // Patterns with no special glob characters should be treated as having asterisks prepended // and appended when testing the condition. - try { - val modPattern = if (pattern.hasSpecialGlobChar()) pattern.simpleGlobToRegExp() else "*$pattern*".simpleGlobToRegExp() - val regex = Regex(modPattern, RegexOption.DOT_MATCHES_ALL) - return regex.containsMatchIn(value) + return try { + if (wordsOnly) { + value.caseInsensitiveFind(pattern) + } else { + val modPattern = if (pattern.hasSpecialGlobChar()) pattern.simpleGlobToRegExp() else "*$pattern*".simpleGlobToRegExp() + val regex = Regex(modPattern, RegexOption.DOT_MATCHES_ALL) + regex.containsMatchIn(value) + } } catch (e: Throwable) { // e.g PatternSyntaxException Timber.e(e, "Failed to evaluate push condition") - return false + false } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt index e16c1df314..29466ca33b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/rest/PushCondition.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.pushrules.ContainsDisplayNameCondition import org.matrix.android.sdk.api.pushrules.EventMatchCondition import org.matrix.android.sdk.api.pushrules.Kind import org.matrix.android.sdk.api.pushrules.RoomMemberCountCondition +import org.matrix.android.sdk.api.pushrules.RuleIds import org.matrix.android.sdk.api.pushrules.SenderNotificationPermissionCondition import timber.log.Timber @@ -59,11 +60,11 @@ data class PushCondition( val iz: String? = null ) { - fun asExecutableCondition(): Condition? { + fun asExecutableCondition(rule: PushRule): Condition? { return when (Kind.fromString(kind)) { Kind.EventMatch -> { if (key != null && pattern != null) { - EventMatchCondition(key, pattern) + EventMatchCondition(key, pattern, rule.ruleId == RuleIds.RULE_ID_CONTAIN_USER_NAME) } else { Timber.e("Malformed Event match condition") null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 49a92acc54..a0667cc4a3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -100,7 +100,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor( return rules.firstOrNull { rule -> // All conditions must hold true for an event in order to apply the action for the event. rule.enabled && rule.conditions?.all { - it.asExecutableCondition()?.isSatisfied(event, conditionResolver) ?: false + it.asExecutableCondition(rule)?.isSatisfied(event, conditionResolver) ?: false } ?: false } } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt index be5aeaaf0f..e428c7ab22 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt @@ -16,6 +16,12 @@ package org.matrix.android.sdk.api.pushrules +import io.mockk.every +import io.mockk.mockk +import org.amshove.kluent.shouldBe +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test import org.matrix.android.sdk.MatrixTest import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toContent @@ -24,12 +30,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent import org.matrix.android.sdk.internal.session.room.RoomGetter -import io.mockk.every -import io.mockk.mockk -import org.amshove.kluent.shouldBe -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test class PushrulesConditionTest: MatrixTest { @@ -39,7 +39,7 @@ class PushrulesConditionTest: MatrixTest { @Test fun test_eventmatch_type_condition() { - val condition = EventMatchCondition("type", "m.room.message") + val condition = EventMatchCondition("type", "m.room.message", false) val simpleTextEvent = Event( type = "m.room.message", @@ -65,7 +65,7 @@ class PushrulesConditionTest: MatrixTest { @Test fun test_eventmatch_path_condition() { - val condition = EventMatchCondition("content.msgtype", "m.text") + val condition = EventMatchCondition("content.msgtype", "m.text", false) val simpleTextEvent = Event( type = "m.room.message", @@ -86,13 +86,13 @@ class PushrulesConditionTest: MatrixTest { ).toContent(), originServerTs = 0 ).apply { - assert(EventMatchCondition("content.membership", "invite").isSatisfied(this)) + assert(EventMatchCondition("content.membership", "invite", false).isSatisfied(this)) } } @Test fun test_eventmatch_cake_condition() { - val condition = EventMatchCondition("content.body", "cake") + val condition = EventMatchCondition("content.body", "cake", false) Event( type = "m.room.message", @@ -115,7 +115,7 @@ class PushrulesConditionTest: MatrixTest { @Test fun test_eventmatch_cakelie_condition() { - val condition = EventMatchCondition("content.body", "cake*lie") + val condition = EventMatchCondition("content.body", "cake*lie", false) val simpleTextEvent = Event( type = "m.room.message", @@ -126,9 +126,22 @@ class PushrulesConditionTest: MatrixTest { assert(condition.isSatisfied(simpleTextEvent)) } + @Test + fun test_eventmatch_words_only_condition() { + val condition = EventMatchCondition("content.body", "ben", true) + + val simpleTextEvent = Event( + type = "m.room.message", + eventId = "mx0", + content = MessageTextContent("m.text", "benoit").toContent(), + originServerTs = 0) + + assertFalse(condition.isSatisfied(simpleTextEvent)) + } + @Test fun test_notice_condition() { - val conditionEqual = EventMatchCondition("content.msgtype", "m.notice") + val conditionEqual = EventMatchCondition("content.msgtype", "m.notice", false) Event( type = "m.room.message", diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRuleItem.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRuleItem.kt index 9799b32c38..0144b162e9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRuleItem.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRuleItem.kt @@ -26,11 +26,11 @@ import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelWithHolder -import org.matrix.android.sdk.api.pushrules.getActions -import org.matrix.android.sdk.api.pushrules.rest.PushRule import im.vector.app.R import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.features.notifications.toNotificationAction +import org.matrix.android.sdk.api.pushrules.getActions +import org.matrix.android.sdk.api.pushrules.rest.PushRule @EpoxyModelClass(layout = R.layout.item_pushrule_raw) abstract class PushRuleItem : EpoxyModelWithHolder() { @@ -68,7 +68,7 @@ abstract class PushRuleItem : EpoxyModelWithHolder() { val description = StringBuffer() pushRule.conditions?.forEachIndexed { i, condition -> if (i > 0) description.append("\n") - description.append(condition.asExecutableCondition()?.technicalDescription() + description.append(condition.asExecutableCondition(pushRule)?.technicalDescription() ?: "UNSUPPORTED") } if (description.isBlank()) { From 8226f60fade4acfe67dae03697fbf09fb8fb87a8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:31:51 +0200 Subject: [PATCH 059/257] Refactor test to avoid duplicated code --- .../api/pushrules/PushrulesConditionTest.kt | 57 +++++-------------- 1 file changed, 15 insertions(+), 42 deletions(-) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt index e428c7ab22..c5bb9cdc8d 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt @@ -31,21 +31,25 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent import org.matrix.android.sdk.internal.session.room.RoomGetter -class PushrulesConditionTest: MatrixTest { +class PushrulesConditionTest : MatrixTest { /* ========================================================================================== * Test EventMatchCondition * ========================================================================================== */ + private fun createSimpleTextEvent(text: String): Event { + return Event( + type = "m.room.message", + eventId = "mx0", + content = MessageTextContent("m.text", text).toContent(), + originServerTs = 0) + } + @Test fun test_eventmatch_type_condition() { val condition = EventMatchCondition("type", "m.room.message", false) - val simpleTextEvent = Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "Yo wtf?").toContent(), - originServerTs = 0) + val simpleTextEvent = createSimpleTextEvent("Yo wtf?") val rm = RoomMemberContent( Membership.INVITE, @@ -67,11 +71,7 @@ class PushrulesConditionTest: MatrixTest { fun test_eventmatch_path_condition() { val condition = EventMatchCondition("content.msgtype", "m.text", false) - val simpleTextEvent = Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "Yo wtf?").toContent(), - originServerTs = 0) + val simpleTextEvent = createSimpleTextEvent("Yo wtf?") assert(condition.isSatisfied(simpleTextEvent)) @@ -94,49 +94,22 @@ class PushrulesConditionTest: MatrixTest { fun test_eventmatch_cake_condition() { val condition = EventMatchCondition("content.body", "cake", false) - Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "How was the cake?").toContent(), - originServerTs = 0 - ).apply { - assert(condition.isSatisfied(this)) - } - - Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "Howwasthecake?").toContent(), - originServerTs = 0 - ).apply { - assert(condition.isSatisfied(this)) - } + assert(condition.isSatisfied(createSimpleTextEvent("How was the cake?"))) + assert(condition.isSatisfied(createSimpleTextEvent("Howwasthecake?"))) } @Test fun test_eventmatch_cakelie_condition() { val condition = EventMatchCondition("content.body", "cake*lie", false) - val simpleTextEvent = Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "How was the cakeisalie?").toContent(), - originServerTs = 0) - - assert(condition.isSatisfied(simpleTextEvent)) + assert(condition.isSatisfied(createSimpleTextEvent("How was the cakeisalie?"))) } @Test fun test_eventmatch_words_only_condition() { val condition = EventMatchCondition("content.body", "ben", true) - val simpleTextEvent = Event( - type = "m.room.message", - eventId = "mx0", - content = MessageTextContent("m.text", "benoit").toContent(), - originServerTs = 0) - - assertFalse(condition.isSatisfied(simpleTextEvent)) + assertFalse(condition.isSatisfied(createSimpleTextEvent("benoit"))) } @Test From 1a068ee191a398cdfe8bdbe2395c54197dcccc7e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:34:02 +0200 Subject: [PATCH 060/257] Add more tests --- .../android/sdk/api/pushrules/PushrulesConditionTest.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt index c5bb9cdc8d..08251062b5 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt @@ -110,6 +110,15 @@ class PushrulesConditionTest : MatrixTest { val condition = EventMatchCondition("content.body", "ben", true) assertFalse(condition.isSatisfied(createSimpleTextEvent("benoit"))) + assertFalse(condition.isSatisfied(createSimpleTextEvent("Hello benoit"))) + assertFalse(condition.isSatisfied(createSimpleTextEvent("superben"))) + + assert(condition.isSatisfied(createSimpleTextEvent("ben"))) + assert(condition.isSatisfied(createSimpleTextEvent("hello ben"))) + assert(condition.isSatisfied(createSimpleTextEvent("ben is there"))) + assert(condition.isSatisfied(createSimpleTextEvent("hello ben!"))) + assert(condition.isSatisfied(createSimpleTextEvent("hello Ben!"))) + assert(condition.isSatisfied(createSimpleTextEvent("BEN"))) } @Test From 5e0fc3e17f9c4296f86f0b5216ba35543797cb37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:34:43 +0200 Subject: [PATCH 061/257] Rename class --- .../{PushrulesConditionTest.kt => PushRulesConditionTest.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/{PushrulesConditionTest.kt => PushRulesConditionTest.kt} (99%) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRulesConditionTest.kt similarity index 99% rename from matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt rename to matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRulesConditionTest.kt index 08251062b5..b2c8d3bda8 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushrulesConditionTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/api/pushrules/PushRulesConditionTest.kt @@ -31,7 +31,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent import org.matrix.android.sdk.internal.session.room.RoomGetter -class PushrulesConditionTest : MatrixTest { +class PushRulesConditionTest : MatrixTest { /* ========================================================================================== * Test EventMatchCondition From 6376ba2516744777ff7d8d4a5dc8fd5e1034f79e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Aug 2020 17:48:12 +0200 Subject: [PATCH 062/257] Improve wording (visible in debug screen) --- .../org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt index c10d2fc1df..c9aa0d001a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/EventMatchCondition.kt @@ -43,7 +43,7 @@ class EventMatchCondition( return conditionResolver.resolveEventMatchCondition(event, this) } - override fun technicalDescription() = "'$key' Matches '$pattern', words only '$wordsOnly'" + override fun technicalDescription() = "'$key' matches '$pattern', words only '$wordsOnly'" fun isSatisfied(event: Event): Boolean { // TODO encrypted events? From 9970398cf2ea7177186c4c5651a2ec0ab7f91656 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Aug 2020 20:20:14 +0200 Subject: [PATCH 063/257] Join room: add "UnknownItem" to public room list --- .../features/navigation/DefaultNavigator.kt | 19 ++----- .../app/features/navigation/Navigator.kt | 6 +- .../features/permalink/PermalinkHandler.kt | 36 ++++++++++-- .../roomdirectory/PublicRoomsController.kt | 33 ++++++++++- .../roomdirectory/PublicRoomsFragment.kt | 27 ++++++++- .../features/roomdirectory/UnknownRoomItem.kt | 57 +++++++++++++++++++ .../roompreview/RoomPreviewActivity.kt | 23 ++++---- .../src/main/res/layout/item_unknown_room.xml | 52 +++++++++++++++++ vector/src/main/res/values/strings.xml | 2 + 9 files changed, 218 insertions(+), 37 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt create mode 100644 vector/src/main/res/layout/item_unknown_room.xml diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index ea35bbc087..884433431b 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -158,18 +158,6 @@ class DefaultNavigator @Inject constructor( } } - override fun openNotJoinedRoom(context: Context, roomId: String, eventId: String?, roomSummary: RoomSummary?, buildTask: Boolean) { - val roomPreviewData = RoomPreviewData( - roomId = roomId, - eventId = eventId, - roomAlias = roomSummary?.canonicalAlias, - roomName = roomSummary?.displayName, - avatarUrl = roomSummary?.avatarUrl - ) - val intent = RoomPreviewActivity.newIntent(context, roomPreviewData) - context.startActivity(intent) - } - override fun openGroupDetail(groupId: String, context: Context, buildTask: Boolean) { if (context is VectorBaseActivity) { context.notImplemented("Open group detail") @@ -192,7 +180,12 @@ class DefaultNavigator @Inject constructor( } override fun openRoomPreview(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData) { - val intent = RoomPreviewActivity.getIntent(context, publicRoom, roomDirectoryData) + val intent = RoomPreviewActivity.newIntent(context, publicRoom, roomDirectoryData) + context.startActivity(intent) + } + + override fun openRoomPreview(context: Context, roomPreviewData: RoomPreviewData) { + val intent = RoomPreviewActivity.newIntent(context, roomPreviewData) context.startActivity(intent) } diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index b26c2711c7..506da5bd3d 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -25,6 +25,7 @@ import im.vector.app.features.home.room.detail.widget.WidgetRequestCodes import im.vector.app.features.media.AttachmentData import im.vector.app.features.pin.PinActivity import im.vector.app.features.pin.PinMode +import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.share.SharedData import im.vector.app.features.terms.ReviewTermsActivity @@ -51,10 +52,10 @@ interface Navigator { fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) - fun openNotJoinedRoom(context: Context, roomId: String, eventId: String? = null, roomSummary: RoomSummary?, buildTask: Boolean = false) - fun openRoomPreview(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData) + fun openRoomPreview(context: Context, roomPreviewData: RoomPreviewData) + fun openCreateRoom(context: Context, initialName: String = "") fun openCreateDirectRoom(context: Context) @@ -106,4 +107,5 @@ interface Navigator { view: View, inMemory: List = emptyList(), options: ((MutableList>) -> Unit)?) + } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 8ab716d01d..cd26027f94 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -18,9 +18,11 @@ package im.vector.app.features.permalink import android.content.Context import android.net.Uri +import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.utils.toast import im.vector.app.features.navigation.Navigator +import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import io.reactivex.Single import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -61,7 +63,13 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti .map { val roomId = it.getOrNull() if (navigationInterceptor?.navToRoom(roomId, permalinkData.eventId) != true) { - openRoom(context, roomId, permalinkData.eventId, buildTask) + openRoom( + context = context, + roomId = roomId, + roomAlias = permalinkData.getRoomAliasOrNull(), + eventId = permalinkData.eventId, + buildTask = buildTask + ) } true } @@ -79,7 +87,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti is PermalinkData.FallbackLink -> { Single.just(false) } - } + }.onErrorReturnItem(false) } private fun PermalinkData.RoomLink.getRoomId(): Single> { @@ -91,13 +99,21 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } + private fun PermalinkData.RoomLink.getRoomAliasOrNull(): String? { + return if (isRoomAlias) { + roomIdOrAlias + } else { + null + } + } + /** * Open room either joined, or not */ - private fun openRoom(context: Context, roomId: String?, eventId: String?, buildTask: Boolean) { + private fun openRoom(context: Context, roomId: String?, roomAlias: String?, eventId: String?, buildTask: Boolean) { val session = activeSessionHolder.getSafeActiveSession() ?: return if (roomId == null) { - context.toast("Couldn't get roomId in permalink data.") + context.toast(R.string.room_error_not_found) return } val roomSummary = session.getRoomSummary(roomId) @@ -106,10 +122,18 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigator.openRoom(context, roomId, eventId, buildTask) } roomSummary?.membership != Membership.BAN -> { - navigator.openNotJoinedRoom(context, roomId, eventId, roomSummary, buildTask) + val roomPreviewData = RoomPreviewData( + roomId = roomId, + eventId = eventId, + roomAlias = roomAlias ?: roomSummary?.canonicalAlias, + roomName = roomSummary?.displayName, + avatarUrl = roomSummary?.avatarUrl, + buildTask = buildTask + ) + navigator.openRoomPreview(context, roomPreviewData) } else -> { - context.toast("Can't open a room where you are banned from.") + context.toast(R.string.error_opening_banned_room) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt index c60336c1af..18b92abdcf 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt @@ -28,8 +28,10 @@ import im.vector.app.core.epoxy.noResultItem import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer +import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom +import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -42,18 +44,23 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri override fun buildModels(viewState: PublicRoomsViewState) { val publicRooms = viewState.publicRooms - if (publicRooms.isEmpty() - && viewState.asyncPublicRoomsRequest is Success) { + val unknownRoomItem = viewState.buildUnknownRoomIfNeeded() + + val noResult = publicRooms.isEmpty() && viewState.asyncPublicRoomsRequest is Success && unknownRoomItem == null + if (noResult) { // No result noResultItem { id("noResult") text(stringProvider.getString(R.string.no_result_placeholder)) } } else { + publicRooms.forEach { buildPublicRoom(it, viewState) } + unknownRoomItem?.addTo(this) + if ((viewState.hasMore && viewState.asyncPublicRoomsRequest is Success) || viewState.asyncPublicRoomsRequest is Incomplete) { loadingItem { @@ -109,7 +116,29 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri } } + private fun PublicRoomsViewState.buildUnknownRoomIfNeeded(): UnknownRoomItem? { + val roomIdOrAlias = currentFilter.trim() + val isAlias = MatrixPatterns.isRoomAlias(roomIdOrAlias) && !publicRooms.any { it.canonicalAlias == roomIdOrAlias } + val isRoomId = !isAlias && MatrixPatterns.isRoomId(roomIdOrAlias) && !publicRooms.any { it.roomId == roomIdOrAlias } + val roomItem = when { + isAlias -> MatrixItem.RoomAliasItem(roomIdOrAlias, roomIdOrAlias) + isRoomId -> MatrixItem.RoomItem(roomIdOrAlias) + else -> null + } + return roomItem?.let { + UnknownRoomItem_().apply { + id(roomIdOrAlias) + matrixItem(roomItem) + avatarRenderer(this@PublicRoomsController.avatarRenderer) + globalListener { + callback?.onUnknownRoomClicked(roomIdOrAlias) + } + } + } + } + interface Callback { + fun onUnknownRoomClicked(roomIdOrAlias: String) fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: JoinState) fun onPublicRoomJoin(publicRoom: PublicRoom) fun loadMore() diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt index 57006af6f1..b180018480 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt @@ -29,9 +29,13 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.VectorBaseFragment -import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom +import im.vector.app.core.utils.toast +import im.vector.app.features.permalink.NavigationInterceptor +import im.vector.app.features.permalink.PermalinkHandler import io.reactivex.rxkotlin.subscribeBy import kotlinx.android.synthetic.main.fragment_public_rooms.* +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -41,7 +45,9 @@ import javax.inject.Inject * - When filtering more (when entering new chars), we could filter on result we already have, during the new server request, to avoid empty screen effect */ class PublicRoomsFragment @Inject constructor( - private val publicRoomsController: PublicRoomsController + private val publicRoomsController: PublicRoomsController, + private val permalinkHandler: PermalinkHandler, + private val session: Session ) : VectorBaseFragment(), PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() @@ -112,6 +118,23 @@ class PublicRoomsFragment @Inject constructor( publicRoomsController.callback = this } + override fun onUnknownRoomClicked(roomIdOrAlias: String) { + val permalink = session.permalinkService().createPermalink(roomIdOrAlias) + permalinkHandler + .launch(requireContext(), permalink, object : NavigationInterceptor { + override fun navToRoom(roomId: String?, eventId: String?): Boolean { + requireActivity().finish() + return false + } + }) + .subscribe { isSuccessful -> + if (!isSuccessful) { + requireContext().toast(R.string.room_error_not_found) + } + } + .disposeOnDestroyView() + } + override fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: JoinState) { Timber.v("PublicRoomClicked: $publicRoom") withState(viewModel) { state -> diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt new file mode 100644 index 0000000000..cf0ad811a2 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.roomdirectory + +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.features.home.AvatarRenderer +import org.matrix.android.sdk.api.util.MatrixItem + +@EpoxyModelClass(layout = R.layout.item_unknown_room) +abstract class UnknownRoomItem : VectorEpoxyModel() { + + @EpoxyAttribute + lateinit var avatarRenderer: AvatarRenderer + + @EpoxyAttribute + lateinit var matrixItem: MatrixItem + + @EpoxyAttribute + var identifier: String? = null + + @EpoxyAttribute + var globalListener: (() -> Unit)? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.rootView.setOnClickListener { globalListener?.invoke() } + avatarRenderer.render(matrixItem, holder.avatarView) + holder.nameView.text = matrixItem.displayName + } + + class Holder : VectorEpoxyHolder() { + val rootView by bind(R.id.itemUnknownRoomLayout) + val avatarView by bind(R.id.itemUnknownRoomAvatar) + val nameView by bind(R.id.itemUnknownRoomName) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index 9bf5646a99..d304594474 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -56,18 +56,17 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { } } - fun getIntent(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData): Intent { - return Intent(context, RoomPreviewActivity::class.java).apply { - putExtra(ARG, RoomPreviewData( - roomId = publicRoom.roomId, - roomName = publicRoom.name, - roomAlias = publicRoom.getPrimaryAlias(), - topic = publicRoom.topic, - worldReadable = publicRoom.worldReadable, - avatarUrl = publicRoom.avatarUrl, - homeServer = roomDirectoryData.homeServer - )) - } + fun newIntent(context: Context, publicRoom: PublicRoom, roomDirectoryData: RoomDirectoryData): Intent { + val roomPreviewData = RoomPreviewData( + roomId = publicRoom.roomId, + roomName = publicRoom.name, + roomAlias = publicRoom.getPrimaryAlias(), + topic = publicRoom.topic, + worldReadable = publicRoom.worldReadable, + avatarUrl = publicRoom.avatarUrl, + homeServer = roomDirectoryData.homeServer + ) + return newIntent(context, roomPreviewData) } } diff --git a/vector/src/main/res/layout/item_unknown_room.xml b/vector/src/main/res/layout/item_unknown_room.xml new file mode 100644 index 0000000000..a097767e63 --- /dev/null +++ b/vector/src/main/res/layout/item_unknown_room.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + \ 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 0b9cbab57a..7506a4d502 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2539,4 +2539,6 @@ Enable PIN If you want to reset your PIN, tap Forgot PIN to logout and reset. Confirm PIN to disable PIN + Can\'t open a room where you are banned from. + Can\'t find this room. Make sure it exists. From 776d892d27a8e2583b03c912f1d58bb12c7a7cdc Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 26 Aug 2020 12:27:12 +0300 Subject: [PATCH 064/257] Increase version of uCrop library which supports Android 10. --- CHANGES.md | 1 + vector/build.gradle | 2 +- .../im/vector/app/features/media/BigImageViewerActivity.kt | 4 +--- .../im/vector/app/features/roomprofile/RoomProfileFragment.kt | 4 +--- .../app/features/settings/VectorSettingsGeneralFragment.kt | 3 +-- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d3a16c9b29..0ab511820a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Display name not shown under Settings/General (#1926) + - Change user or room avatar: when selecting Gallery, I'm not proposed to crop the selected image (#1590) Translations 🗣: - diff --git a/vector/build.gradle b/vector/build.gradle index c04de62367..ef2d6c3d9e 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -378,7 +378,7 @@ dependencies { implementation "com.github.bumptech.glide:glide:$glide_version" kapt "com.github.bumptech.glide:compiler:$glide_version" implementation 'com.danikula:videocache:2.7.1' - implementation 'com.github.yalantis:ucrop:2.2.4' + implementation 'com.github.yalantis:ucrop:2.2.6' // Badge for compatibility implementation 'me.leolin:ShortcutBadger:1.1.22@aar' diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 9d0a931a32..c619b4aa92 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -144,9 +144,7 @@ class BigImageViewerActivity : VectorBaseActivity() { .get(MultiPicker.IMAGE) .getSelectedFiles(this, requestCode, resultCode, data) .firstOrNull()?.let { - // TODO. UCrop library cannot read from Gallery. For now, we will set avatar as it is. - // onRoomAvatarSelected(it) - onAvatarCropped(it.contentUri) + onRoomAvatarSelected(it) } } UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 2722d54950..075ba1bc10 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -301,9 +301,7 @@ class RoomProfileFragment @Inject constructor( .get(MultiPicker.IMAGE) .getSelectedFiles(requireContext(), requestCode, resultCode, data) .firstOrNull()?.let { - // TODO. UCrop library cannot read from Gallery. For now, we will set avatar as it is. - // onRoomAvatarSelected(it) - onAvatarCropped(it.contentUri) + onRoomAvatarSelected(it) } } UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt index 31de5ddd67..e31b81b162 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsGeneralFragment.kt @@ -356,8 +356,7 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { .get(MultiPicker.IMAGE) .getSelectedFiles(requireContext(), requestCode, resultCode, data) .firstOrNull()?.let { - // TODO. UCrop library cannot read from Gallery. For now, we will set avatar as it is. - onAvatarCropped(it.contentUri) + onAvatarSelected(it) } } UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) } From d014872e3b06c024be4005ec161b81136f637529 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Aug 2020 11:57:27 +0200 Subject: [PATCH 065/257] Add long click gesture to copy userId, user display name, room name, room topic and room alias (#1774) --- CHANGES.md | 2 +- .../im/vector/app/core/extensions/TextView.kt | 17 +++++++++++++++++ .../RoomMemberProfileFragment.kt | 11 +++++++++-- .../roomprofile/RoomProfileFragment.kt | 18 +++++++++++++----- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a9f2e896aa..2135401efb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - Add long click gesture to copy userId, user display name, room name, room topic and room alias (#1774) Bugfix 🐛: - Display name not shown under Settings/General (#1926) diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt index cafcf6d1d8..44b85df93a 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt @@ -24,7 +24,9 @@ import android.widget.TextView import androidx.annotation.AttrRes import androidx.annotation.StringRes import androidx.core.view.isVisible +import com.google.android.material.snackbar.Snackbar import im.vector.app.R +import im.vector.app.core.utils.copyToClipboard import im.vector.app.features.themes.ThemeUtils /** @@ -68,3 +70,18 @@ fun TextView.setTextWithColoredPart(@StringRes fullTextRes: Int, } } } + +/** + * Set long click listener to copy the current text of the TextView to the clipboard and show a Snackbar + */ +fun TextView.copyOnLongClick() { + setOnLongClickListener { view -> + (view as? TextView) + ?.text + ?.let { text -> + copyToClipboard(view.context, text, false) + Snackbar.make(view, view.resources.getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT).show() + } + true + } +} diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index 9c6e813f0b..cda2d83e3d 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -35,6 +35,7 @@ import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener import im.vector.app.core.dialogs.ConfirmationDialogBuilder import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith +import im.vector.app.core.extensions.copyOnLongClick import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.StateView @@ -44,11 +45,11 @@ import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs -import org.matrix.android.sdk.api.session.room.powerlevels.Role -import org.matrix.android.sdk.api.util.MatrixItem import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_matrix_profile.* import kotlinx.android.synthetic.main.view_stub_room_member_profile_header.* +import org.matrix.android.sdk.api.session.room.powerlevels.Role +import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject @Parcelize @@ -110,6 +111,12 @@ class RoomMemberProfileFragment @Inject constructor( is RoomMemberProfileViewEvents.OnInviteActionSuccess -> Unit }.exhaustive } + setupLongClicks() + } + + private fun setupLongClicks() { + memberProfileNameView.copyOnLongClick() + memberProfileIdView.copyOnLongClick() } private fun handleShowPowerLevelDemoteWarning(event: RoomMemberProfileViewEvents.ShowPowerLevelDemoteWarning) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 2722d54950..518932fdcb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -34,16 +34,12 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.yalantis.ucrop.UCrop -import im.vector.lib.multipicker.MultiPicker -import im.vector.lib.multipicker.entity.MultiPickerImageType -import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState -import org.matrix.android.sdk.api.util.MatrixItem -import org.matrix.android.sdk.api.util.toMatrixItem import im.vector.app.R import im.vector.app.core.animations.AppBarStateChangeListener import im.vector.app.core.animations.MatrixItemAppBarStateChangeListener import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith +import im.vector.app.core.extensions.copyOnLongClick import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.intent.getFilenameFromUri @@ -62,9 +58,14 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.media.BigImageViewerActivity import im.vector.app.features.media.createUCropWithDefaultSettings +import im.vector.lib.multipicker.MultiPicker +import im.vector.lib.multipicker.entity.MultiPickerImageType import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_matrix_profile.* import kotlinx.android.synthetic.main.view_stub_room_profile_header.* +import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState +import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.util.toMatrixItem import timber.log.Timber import java.io.File import javax.inject.Inject @@ -120,6 +121,13 @@ class RoomProfileFragment @Inject constructor( .observe() .subscribe { handleQuickActions(it) } .disposeOnDestroyView() + setupLongClicks() + } + + private fun setupLongClicks() { + roomProfileNameView.copyOnLongClick() + roomProfileAliasView.copyOnLongClick() + roomProfileTopicView.copyOnLongClick() } override fun onOptionsItemSelected(item: MenuItem): Boolean { From ef912e066bafabc909d17a10dcb6d0d18d3f6953 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Aug 2020 12:29:46 +0200 Subject: [PATCH 066/257] Remove unused resource --- .../disclaimer_top_banner_foreground.xml | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 vector/src/main/res/drawable/disclaimer_top_banner_foreground.xml diff --git a/vector/src/main/res/drawable/disclaimer_top_banner_foreground.xml b/vector/src/main/res/drawable/disclaimer_top_banner_foreground.xml deleted file mode 100644 index c031da1e5b..0000000000 --- a/vector/src/main/res/drawable/disclaimer_top_banner_foreground.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - From 9f3f981ab07fdf0813b860415949a459cc585a09 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Aug 2020 12:30:26 +0200 Subject: [PATCH 067/257] Use cached Views --- .../im/vector/app/core/preference/PushRulePreference.kt | 3 +-- .../app/core/preference/VectorEditTextPreference.kt | 2 +- .../im/vector/app/core/preference/VectorPreference.kt | 8 ++++---- .../app/core/preference/VectorPreferenceCategory.kt | 2 +- .../vector/app/core/preference/VectorSwitchPreference.kt | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt index 87584a9db0..9c4878ef06 100755 --- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt @@ -20,7 +20,6 @@ import android.content.Context import android.util.AttributeSet import android.view.View import android.widget.RadioGroup -import android.widget.TextView import androidx.preference.PreferenceViewHolder import im.vector.app.R import org.matrix.android.sdk.api.pushrules.RuleSetKey @@ -162,7 +161,7 @@ class PushRulePreference : VectorPreference { override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) - holder.itemView.findViewById(android.R.id.summary)?.visibility = View.GONE + holder.findViewById(android.R.id.summary)?.visibility = View.GONE holder.itemView.setOnClickListener(null) holder.itemView.setOnLongClickListener(null) diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorEditTextPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorEditTextPreference.kt index 840e5fa510..348fcffc9b 100644 --- a/vector/src/main/java/im/vector/app/core/preference/VectorEditTextPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorEditTextPreference.kt @@ -45,7 +45,7 @@ class VectorEditTextPreference : EditTextPreference { override fun onBindViewHolder(holder: PreferenceViewHolder) { // display the title in multi-line to avoid ellipsis. try { - holder.itemView.findViewById(android.R.id.title)?.isSingleLine = false + (holder.findViewById(android.R.id.title) as? TextView)?.isSingleLine = false } catch (e: Exception) { Timber.e(e, "onBindView") } diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt index 4a9bb6a6f5..dd887dba67 100755 --- a/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt @@ -84,15 +84,15 @@ open class VectorPreference : Preference { // display the title in multi-line to avoid ellipsis. try { - val title = itemView.findViewById(android.R.id.title) - val summary = itemView.findViewById(android.R.id.summary) + val title = holder.findViewById(android.R.id.title) as? TextView + val summary = holder.findViewById(android.R.id.summary) as? TextView if (title != null) { title.isSingleLine = false title.setTypeface(null, mTypeface) } - if (title !== summary) { - summary.setTypeface(null, mTypeface) + summary?.setTypeface(null, mTypeface) + } // cancel existing animation (find a way to resume if happens during anim?) diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorPreferenceCategory.kt b/vector/src/main/java/im/vector/app/core/preference/VectorPreferenceCategory.kt index e61cde8ebd..eb59da640d 100644 --- a/vector/src/main/java/im/vector/app/core/preference/VectorPreferenceCategory.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorPreferenceCategory.kt @@ -45,7 +45,7 @@ class VectorPreferenceCategory : PreferenceCategory { override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) - val titleTextView = holder.itemView.findViewById(android.R.id.title) + val titleTextView = holder.findViewById(android.R.id.title) as? TextView titleTextView?.setTypeface(null, Typeface.BOLD) titleTextView?.setTextColor(ThemeUtils.getColor(context, R.attr.riotx_text_primary)) diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorSwitchPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorSwitchPreference.kt index c97991bfcb..346e8488b9 100644 --- a/vector/src/main/java/im/vector/app/core/preference/VectorSwitchPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorSwitchPreference.kt @@ -58,7 +58,7 @@ class VectorSwitchPreference : SwitchPreference { override fun onBindViewHolder(holder: PreferenceViewHolder) { // display the title in multi-line to avoid ellipsis. - holder.itemView.findViewById(android.R.id.title)?.isSingleLine = false + (holder.findViewById(android.R.id.title) as? TextView)?.isSingleLine = false // cancel existing animation (find a way to resume if happens during anim?) currentHighlightAnimator?.cancel() From 249f268fb52b949926a1dad4089b8d27547453bb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Aug 2020 12:55:49 +0200 Subject: [PATCH 068/257] Fix bad color for settings icon on Android < 24 (#1786) --- CHANGES.md | 1 + .../app/core/preference/VectorPreference.kt | 17 +++++++++++++++++ .../settings/VectorSettingsRootFragment.kt | 13 ++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a9f2e896aa..f7682028e1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Improvements 🙌: Bugfix 🐛: - Display name not shown under Settings/General (#1926) + - Fix bad color for settings icon on Android < 24 (#1786) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt b/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt index dd887dba67..a40ddef6ab 100755 --- a/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/VectorPreference.kt @@ -20,12 +20,15 @@ import android.animation.Animator import android.animation.ArgbEvaluator import android.animation.ValueAnimator import android.content.Context +import android.content.res.ColorStateList import android.graphics.Color import android.graphics.Typeface import android.util.AttributeSet import android.view.View +import android.widget.ImageView import android.widget.TextView import androidx.core.animation.doOnEnd +import androidx.core.widget.ImageViewCompat import androidx.preference.Preference import androidx.preference.PreferenceViewHolder import im.vector.app.R @@ -76,6 +79,12 @@ open class VectorPreference : Preference { notifyChanged() } + var tintIcon = false + set(value) { + field = value + notifyChanged() + } + var currentHighlightAnimator: Animator? = null override fun onBindViewHolder(holder: PreferenceViewHolder) { @@ -93,6 +102,14 @@ open class VectorPreference : Preference { summary?.setTypeface(null, mTypeface) + if (tintIcon) { + // Tint icons (See #1786) + val icon = holder.findViewById(android.R.id.icon) as? ImageView + + icon?.let { + val color = ThemeUtils.getColor(context, R.attr.riotx_header_panel_text_secondary) + ImageViewCompat.setImageTintList(it, ColorStateList.valueOf(color)) + } } // cancel existing animation (find a way to resume if happens during anim?) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt index d2ec1a1543..3f3811ce76 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.settings +import android.os.Build import im.vector.app.R +import im.vector.app.core.preference.VectorPreference import javax.inject.Inject class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragment() { @@ -25,6 +27,15 @@ class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragm override val preferenceXmlRes = R.xml.vector_settings_root override fun bindPref() { - // Nothing to do + // Tint icon on API < 24 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + tintIcons() + } + } + + private fun tintIcons() { + for (i in 0 until preferenceScreen.preferenceCount) { + (preferenceScreen.getPreference(i) as? VectorPreference)?.let { it.tintIcon = true } + } } } From 25ea221d4727c1cbba6a29ce5a742db65c17cc4d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Aug 2020 15:28:48 +0200 Subject: [PATCH 069/257] Create a script to import SAS strings (#1909) It will be run at the next Weblate sync, since we have to remove previous translations --- CHANGES.md | 1 + tools/import_sas_strings.py | 103 ++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100755 tools/import_sas_strings.py diff --git a/CHANGES.md b/CHANGES.md index f48436d279..ab4a121c6a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Build 🧱: Other changes: - Use File extension functions to make code more concise (#1996) + - Create a script to import SAS strings (#1909) Changes in Element 1.0.5 (2020-08-21) =================================================== diff --git a/tools/import_sas_strings.py b/tools/import_sas_strings.py new file mode 100755 index 0000000000..faf4ed7080 --- /dev/null +++ b/tools/import_sas_strings.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +# 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. + +import argparse +import json +import os +import os.path +# Run `pip3 install requests` if not installed yet +import requests + +### Arguments + +parser = argparse.ArgumentParser(description='Download sas string from matrix-doc.') +parser.add_argument('-v', + '--verbose', + help="increase output verbosity.", + action="store_true") + +args = parser.parse_args() + +if args.verbose: + print("Argument:") + print(args) + +base_url = "https://raw.githubusercontent.com/matrix-org/matrix-doc/master/data-definitions/sas-emoji.json" + +print("Downloading " + base_url + "…") + +r0 = requests.get(base_url) +data0 = json.loads(r0.content.decode()) + +if args.verbose: + print("Json data:") + print(data0) + +print() + +# emoji -> translation +default = dict() +# Language -> emoji -> translation +cumul = dict() + +for emoji in data0: + description = emoji["description"] + if args.verbose: + print("Description: " + description) + default[description] = description + + for lang in emoji["translated_descriptions"]: + if args.verbose: + print("Lang: " + lang) + if not (lang in cumul): + cumul[lang] = dict() + cumul[lang][description] = emoji["translated_descriptions"][lang] + +if args.verbose: + print(default) + print(cumul) + +def write_file(file, dict): + print("Writing file " + file) + if args.verbose: + print("With") + print(dict) + os.makedirs(os.path.dirname(file), exist_ok=True) + with open(file, mode="w", encoding="utf8") as o: + o.write("\n") + o.write("\n") + o.write(" \n") + for key in dict: + if dict[key] is None: + continue + o.write(" " + dict[key].replace("'", "\\'") + "\n") + o.write("\n") + +scripts_dir = os.path.dirname(os.path.abspath(__file__)) +data_defs_dir = os.path.join(scripts_dir, "../matrix-sdk-android/src/main/res") + +# Write default file +write_file(os.path.join(data_defs_dir, "values/strings_sas.xml"), default) + +# Write each language file +for lang in cumul: + androidLang = lang\ + .replace("_", "-r")\ + .replace("zh-rHans", "zh-rCN") + write_file(os.path.join(data_defs_dir, "values-" + androidLang + "/strings_sas.xml"), cumul[lang]) + +print() +print("Success!") From b986bfd5095559a53e4fa40b47ca01415e3ef19a Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 16:37:48 +0200 Subject: [PATCH 070/257] Permalink: handle via parameters --- .../api/session/permalinks/PermalinkData.kt | 7 ++- .../api/session/permalinks/PermalinkParser.kt | 52 +++++++++++++++++-- .../features/permalink/PermalinkHandler.kt | 37 ++++++++++--- .../roompreview/RoomPreviewActivity.kt | 4 +- .../roompreview/RoomPreviewViewModel.kt | 5 +- .../roompreview/RoomPreviewViewState.kt | 7 ++- 6 files changed, 91 insertions(+), 21 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt index 85632d6e83..1da65b3002 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkData.kt @@ -25,7 +25,12 @@ import android.net.Uri */ sealed class PermalinkData { - data class RoomLink(val roomIdOrAlias: String, val isRoomAlias: Boolean, val eventId: String?) : PermalinkData() + data class RoomLink( + val roomIdOrAlias: String, + val isRoomAlias: Boolean, + val eventId: String?, + val viaParameters: List + ) : PermalinkData() data class UserLink(val userId: String) : PermalinkData() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index dd6847f1e3..d741367376 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -19,6 +19,10 @@ package org.matrix.android.sdk.api.session.permalinks import android.net.Uri import org.matrix.android.sdk.api.MatrixPatterns +import java.io.UnsupportedEncodingException +import java.net.URLEncoder +import java.util.ArrayList +import java.util.Collections /** * This class turns an uri to a [PermalinkData] @@ -40,14 +44,13 @@ object PermalinkParser { if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) { return PermalinkData.FallbackLink(uri) } - val fragment = uri.fragment if (fragment.isNullOrEmpty()) { return PermalinkData.FallbackLink(uri) } - val indexOfQuery = fragment.indexOf("?") val safeFragment = if (indexOfQuery != -1) fragment.substring(0, indexOfQuery) else fragment + val viaQueryParameters = fragment.getViaParameters(indexOfQuery) // we are limiting to 2 params val params = safeFragment @@ -65,17 +68,58 @@ object PermalinkParser { PermalinkData.RoomLink( roomIdOrAlias = identifier, isRoomAlias = false, - eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) } + eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) }, + viaParameters = viaQueryParameters ) } MatrixPatterns.isRoomAlias(identifier) -> { PermalinkData.RoomLink( roomIdOrAlias = identifier, isRoomAlias = true, - eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) } + eventId = extraParameter.takeIf { !it.isNullOrEmpty() && MatrixPatterns.isEventId(it) }, + viaParameters = viaQueryParameters ) } else -> PermalinkData.FallbackLink(uri) } } + + private fun String.getViaParameters(indexOfQuery: Int): List { + val query = try { + substring(indexOfQuery + 1) + } catch (e: IndexOutOfBoundsException) { + return emptyList() + } + val encodedKey = try { + URLEncoder.encode("via", "UTF-8") + } catch (e: UnsupportedEncodingException) { + return emptyList() + } + val values = ArrayList() + var start = 0 + do { + val nextAmpersand = query.indexOf('&', start) + val end = if (nextAmpersand != -1) nextAmpersand else query.length + var separator = query.indexOf('=', start) + if (separator > end || separator == -1) { + separator = end + } + if (separator - start == encodedKey.length + && query.regionMatches(start, encodedKey, 0, encodedKey.length)) { + if (separator == end) { + values.add("") + } else { + values.add(Uri.decode(query.substring(separator + 1, end))) + } + } + + // Move start to end of name. + start = if (nextAmpersand != -1) { + nextAmpersand + 1 + } else { + break + } + } while (true) + return Collections.unmodifiableList(values) + } } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index cd26027f94..4ca16888a5 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -56,7 +56,25 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti if (deepLink == null) { return Single.just(false) } - return when (val permalinkData = PermalinkParser.parse(deepLink)) { + return Single + .fromCallable { + PermalinkParser.parse(deepLink) + } + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .flatMap { permalinkData -> + handlePermalink(permalinkData, context, navigationInterceptor, buildTask) + } + .onErrorReturnItem(false) + } + + private fun handlePermalink( + permalinkData: PermalinkData, + context: Context, + navigationInterceptor: NavigationInterceptor?, + buildTask: Boolean + ): Single { + return when (permalinkData) { is PermalinkData.RoomLink -> { permalinkData.getRoomId() .observeOn(AndroidSchedulers.mainThread()) @@ -66,8 +84,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti openRoom( context = context, roomId = roomId, - roomAlias = permalinkData.getRoomAliasOrNull(), - eventId = permalinkData.eventId, + permalinkData = permalinkData, buildTask = buildTask ) } @@ -87,7 +104,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti is PermalinkData.FallbackLink -> { Single.just(false) } - }.onErrorReturnItem(false) + } } private fun PermalinkData.RoomLink.getRoomId(): Single> { @@ -110,13 +127,20 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti /** * Open room either joined, or not */ - private fun openRoom(context: Context, roomId: String?, roomAlias: String?, eventId: String?, buildTask: Boolean) { + private fun openRoom( + context: Context, + roomId: String?, + permalinkData: PermalinkData.RoomLink, + buildTask: Boolean + ) { val session = activeSessionHolder.getSafeActiveSession() ?: return if (roomId == null) { context.toast(R.string.room_error_not_found) return } val roomSummary = session.getRoomSummary(roomId) + val eventId = permalinkData.eventId + val roomAlias = permalinkData.getRoomAliasOrNull() return when { roomSummary?.membership?.isActive().orFalse() -> { navigator.openRoom(context, roomId, eventId, buildTask) @@ -128,7 +152,8 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti roomAlias = roomAlias ?: roomSummary?.canonicalAlias, roomName = roomSummary?.displayName, avatarUrl = roomSummary?.avatarUrl, - buildTask = buildTask + buildTask = buildTask, + homeServers = permalinkData.viaParameters ) navigator.openRoomPreview(context, roomPreviewData) } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index d304594474..8bbaa14ab0 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -38,7 +38,7 @@ data class RoomPreviewData( val topic: String? = null, val worldReadable: Boolean = false, val avatarUrl: String? = null, - val homeServer: String? = null, + val homeServers: List = emptyList(), val buildTask: Boolean = false ) : Parcelable { val matrixItem: MatrixItem @@ -64,7 +64,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { topic = publicRoom.topic, worldReadable = publicRoom.worldReadable, avatarUrl = publicRoom.avatarUrl, - homeServer = roomDirectoryData.homeServer + homeServers = listOfNotNull(roomDirectoryData.homeServer) ) return newIntent(context, roomPreviewData) } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 04b7c33fb2..900ba537b5 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -106,10 +106,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini Timber.w("Try to join an already joining room. Should not happen") return@withState } - val viaServers = state.homeServer?.let { - listOf(it) - } ?: emptyList() - session.joinRoom(state.roomId, viaServers = viaServers, callback = object : MatrixCallback { + session.joinRoom(state.roomId, viaServers = state.homeServers, callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt index f461225e2d..6816e54481 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewState.kt @@ -24,10 +24,9 @@ data class RoomPreviewViewState( val roomId: String = "", val roomAlias: String? = null, /** - * The server name (might be null) - * Set null when the server is the current user's home server. + * Can be empty when the server is the current user's home server. */ - val homeServer: String? = null, + val homeServers: List = emptyList(), // Current state of the room in preview val roomJoinState: JoinState = JoinState.NOT_JOINED, // Last error of join room request @@ -37,6 +36,6 @@ data class RoomPreviewViewState( constructor(args: RoomPreviewData) : this( roomId = args.roomId, roomAlias = args.roomAlias, - homeServer = args.homeServer + homeServers = args.homeServers ) } From 5d8d9cb19c56d6968ded704d816dafdf0b84c717 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 17:02:24 +0200 Subject: [PATCH 071/257] Clean files --- .../java/im/vector/app/features/navigation/DefaultNavigator.kt | 1 - .../main/java/im/vector/app/features/navigation/Navigator.kt | 2 -- .../vector/app/features/roomdirectory/PublicRoomsController.kt | 1 - 3 files changed, 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 884433431b..5de8796c06 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -65,7 +65,6 @@ import im.vector.app.features.terms.ReviewTermsActivity import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction -import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.session.terms.TermsService diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 506da5bd3d..ed710a124f 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -29,7 +29,6 @@ import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.share.SharedData import im.vector.app.features.terms.ReviewTermsActivity -import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.session.terms.TermsService @@ -107,5 +106,4 @@ interface Navigator { view: View, inMemory: List = emptyList(), options: ((MutableList>) -> Unit)?) - } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt index 18b92abdcf..a35725815b 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt @@ -54,7 +54,6 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri text(stringProvider.getString(R.string.no_result_placeholder)) } } else { - publicRooms.forEach { buildPublicRoom(it, viewState) } From 9c151417a823425313444212a591404c4fc333af Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 17:03:51 +0200 Subject: [PATCH 072/257] Update CHANGES --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index d3a16c9b29..43a05e8a90 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ Features ✨: - Improvements 🙌: - - + - You can now join room through permalink and within room directory search Bugfix 🐛: - Display name not shown under Settings/General (#1926) From cefdbe1d083bbb7bd612260efa44b46b8fdf7808 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 19:21:14 +0200 Subject: [PATCH 073/257] Add CheckNumberType in json to fix sending in room v6 --- .../network/parsing/CheckNumberType.kt | 66 +++++++++++++++++++ .../internal/worker/WorkerParamsFactory.kt | 15 ++++- 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt new file mode 100644 index 0000000000..d4ceca2006 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.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 org.matrix.android.sdk.internal.network.parsing + +import androidx.annotation.Nullable +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter + +import com.squareup.moshi.Moshi +import java.io.IOException +import java.lang.reflect.Type +import java.math.BigDecimal + +/** + * This is used to check if NUMBER in json is integer or double, so we can preserve typing when serializing/deserializing in a row. + */ +interface CheckNumberType { + + companion object { + val JSON_ADAPTER_FACTORY = object : JsonAdapter.Factory { + @Nullable + override fun create(type: Type, annotations: Set?, moshi: Moshi): JsonAdapter<*>? { + if (type !== Any::class.java) { + return null + } + val delegate: JsonAdapter = moshi.nextAdapter(this, Any::class.java, emptySet()) + return object : JsonAdapter() { + @Nullable + @Throws(IOException::class) + override fun fromJson(reader: JsonReader): Any? { + return if (reader.peek() !== JsonReader.Token.NUMBER) { + delegate.fromJson(reader) + } else { + val numberAsString = reader.nextString() + val decimal = BigDecimal(numberAsString) + if (decimal.scale() <= 0) { + decimal.intValueExact() + } else { + decimal.toDouble() + } + } + } + + override fun toJson(writer: JsonWriter, value: Any?) { + delegate.toJson(writer, value) + } + } + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt index 2b7cba0b0c..b162566403 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/WorkerParamsFactory.kt @@ -19,13 +19,23 @@ package org.matrix.android.sdk.internal.worker import androidx.work.Data import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.network.parsing.CheckNumberType -object WorkerParamsFactory { +internal object WorkerParamsFactory { + + val moshi by lazy { + // We are adding the CheckNumberType as we are serializing/deserializing multiple time in a row + // and we lost typing information doing so. + // We don't want this check to be done on all adapters, so we just add it here. + MoshiProvider.providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() + } const val KEY = "WORKER_PARAMS_JSON" inline fun toData(params: T): Data { - val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(T::class.java) val json = adapter.toJson(params) return Data.Builder().putString(KEY, json).build() @@ -36,7 +46,6 @@ object WorkerParamsFactory { return if (json == null) { null } else { - val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(T::class.java) adapter.fromJson(json) } From dc4135b506139042d4eed14bf6ddac89f55a0a20 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 19:21:41 +0200 Subject: [PATCH 074/257] Remove unnecessary code now we have an other way to keep number types --- .../internal/session/room/send/SendEventWorker.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt index 2868ce29c1..d37b5e90c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt @@ -21,16 +21,16 @@ import android.content.Context import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.shouldBeRetried +import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import org.matrix.android.sdk.internal.worker.getSessionComponent -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -47,12 +47,10 @@ internal class SendEventWorker(context: Context, @JsonClass(generateAdapter = true) internal data class Params( override val sessionId: String, - // TODO remove after some time, it's used for compat val event: Event? = null, val eventId: String? = null, val roomId: String? = null, val type: String? = null, - val contentStr: String? = null, override val lastFailureMessage: String? = null ) : SessionWorkerParams { @@ -61,7 +59,7 @@ internal class SendEventWorker(context: Context, eventId = event.eventId, roomId = event.roomId, type = event.type, - contentStr = ContentMapper.map(event.content), + event = event, lastFailureMessage = lastFailureMessage ) } @@ -91,7 +89,7 @@ internal class SendEventWorker(context: Context, .also { Timber.e("Work cancelled due to input error from parent") } } return try { - sendEvent(params.eventId, params.roomId, params.type, params.contentStr) + sendEvent(params.eventId, params.roomId, params.type, params.event?.content) Result.success() } catch (exception: Throwable) { // It does start from 0, we want it to stop if it fails the third time @@ -105,10 +103,10 @@ internal class SendEventWorker(context: Context, } } - private suspend fun sendEvent(eventId: String, roomId: String, type: String, contentStr: String?) { + private suspend fun sendEvent(eventId: String, roomId: String, type: String, content: Content?) { localEchoRepository.updateSendState(eventId, SendState.SENDING) executeRequest(eventBus) { - apiCall = roomAPI.send(eventId, roomId, type, contentStr) + apiCall = roomAPI.send(eventId, roomId, type, content) } localEchoRepository.updateSendState(eventId, SendState.SENT) } From 3c0177c2dd1a42f76380a533e5b4348d3e2f289b Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Aug 2020 19:25:20 +0200 Subject: [PATCH 075/257] Update CHANGES --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c923053b24..5d58668790 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bugfix 🐛: - Fix FontSize issue (#1483, #1787) - Fix bad color for settings icon on Android < 24 (#1786) - Change user or room avatar: when selecting Gallery, I'm not proposed to crop the selected image (#1590) + - Fix uploads still don't work with room v6 (#1879) Translations 🗣: - From 6d73f7b767ce4e6cfbd474d19aa22ce20602cfad Mon Sep 17 00:00:00 2001 From: Tirifto Date: Wed, 26 Aug 2020 12:50:05 +0000 Subject: [PATCH 076/257] Translated using Weblate (Esperanto) Currently translated at 25.1% (465 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/eo/ --- vector/src/main/res/values-eo/strings.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index 0e4c464b9c..91ddaae665 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -42,7 +42,7 @@ Vidi fonton Vidi malĉifritan fonton Forigi - Renomi + Alinomi Detaloj pri ano Historia Raporti enhavon @@ -105,14 +105,14 @@ 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. + Progresas savkopio de ŝlosiloj. 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. + Vi perdos aliron al viaj ĉifritaj mesaĝoj, se vi ne savkopios viajn ŝlosilojn antaŭ adiaŭo. Resti Neniu @@ -598,8 +598,9 @@ Agordoj de konto. Sciigoj estas ŝaltitaj por via konto. Ludi - Paûzi + Paŭzi Eksigi - +Vi ne havas permeson ekigi grupan vokon en ĉi tiu ĉambro + From f26c58fa226a6a640632dcf2d6e0cf58df004f31 Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Tue, 25 Aug 2020 19:59:57 +0000 Subject: [PATCH 077/257] Translated using Weblate (Kabyle) Currently translated at 100.0% (3 of 3 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.riot.im/projects/element-android/element-store/kab/ --- .../play/listings/kab/full_description.txt | 30 +++++++++++++++++++ .../play/listings/kab/short_description.txt | 1 + 2 files changed, 31 insertions(+) create mode 100644 vector/src/main/play/listings/kab/full_description.txt create mode 100644 vector/src/main/play/listings/kab/short_description.txt diff --git a/vector/src/main/play/listings/kab/full_description.txt b/vector/src/main/play/listings/kab/full_description.txt new file mode 100644 index 0000000000..019294e869 --- /dev/null +++ b/vector/src/main/play/listings/kab/full_description.txt @@ -0,0 +1,30 @@ +Element d anaw amaynut n usnas n tirawt d uttekki ara: + +1. Ad ak•am-yefken tazmert n usenqed akken ad tḥerzeḍ tabaḍnit-ik•im +2. Ad k•kem-yeǧǧ ad temmeslayeḍ d yal yiwen deg neɣ akkin i uẓeṭṭa n Matrix s usekcem n yisnasen am Slack +3. Ad k•kem-immesten seg udellel, asekyed n yisefka d tebḥirin tufrigin +4. Ad k•kem-iɣelles s uwgelhen seg yixef ɣer yixef, s uzmal anmidag i usenqed n wiyaḍ + +Element yemgarad aṭas ɣef yisnasen-nniḍen n tirawt d uttekki acku mačči d aslammas yerna d aɣbalu yeldin. + +Element ad k•kem-yeǧǧ ad tsennefɣeḍ iman-ik•im - neɣ ad tferneḍ asenneftaɣ - akken ad tesɛuḍ tabaḍnit, ad tesneqdeḍ isefka-k•m d yidiwenniyen-ik•im. Ad ak•am-yefk tasiregt ad tkecmeḍ ɣer uẓeṭṭa yeldin, akken ur tettɣimiḍ ara tettmeslayeḍ d yiseqdacen n Element kan. Yerna d aɣellsan nezzeh. + +Element yezmer ad yeg akk aya acku yetteddu deg Matrix - alugen i teɣwalt yeldin ur nelli d taslammast. + +Element ad ak•am-yefk tazmert ad tferneḍ asenneftaɣ i yidiwenniyen-ik•im. Seg usnas n Element, tzemreḍ ad tferneḍ ad tsennefɣeḍ s yiberdan yemgaraden: + +1. Ldi amiḍan baṭel deg uqeddac azayez n Matrix.org +2. Sennefteɣ amiḍan-ik•im s yiman-ik•im s usenker n uqeddac deg warrum-ik•im +3. Jerred i umiḍan deg uqeddac yugnen s umulteɣ ɣer tɣerɣert n usennefteɣ n Element Matrix Services + +Iwacu ara tferneḍ Element? + +SƐU ISEFKA-INEK•INEM: D kečč/kemm ara ifernen anda ara tḥerzeḍ isefka-k•m d yiznan-ik•im. D ayla-k•m, d kečč/kemm ara t-isneqden, mačči d kra n MEGACORP ara yamden isefka-k•m neɣ ara yefken tasiregt n unekcum i wis tlata. + +TIRAWT YELDIN D UTTEKKI: Tzemreḍ ad temmeslayeḍ d yal yiwen deg uẓeṭṭa n Matrix, ɣas seqdacen Element neɣ asnas-nniḍen n Matrix, ulamma daɣen seqdacen anagraw n tirawt yemgaraden am Slack, IRC neɣ XMPP. + +D AƔELLSAN NEZZEH: Awgelhen seg yixef ɣer yixef n tidet (anagar wid/tid i yellan deg udiwenni i izemren ad zemken iznan), d uzmal anmidag i usenqed n yibenken n yimettekkiyen deg udiwenni. + +TAƔWALT TUMMIDT: Tirawt, isawalen s taɣect neɣ s tvidyut, beṭṭu n yifuyla, beṭṭu n ugdil d waṭas n yimsidaf, ibuṭen d yiwiǧiten. Bnu tixxamin, timezdagnutin, ḍfer amaynut tfakkeḍ timahilin. + +ANDA TEBƔUḌ TILIḌ: Ḍfer amaynut anda tebɣuḍ tiliḍ s umazray ummid n yiznan yemtawan deg akk ibenken-ik•im, daɣen deg web deg https://app.element.io. diff --git a/vector/src/main/play/listings/kab/short_description.txt b/vector/src/main/play/listings/kab/short_description.txt new file mode 100644 index 0000000000..bee72ea427 --- /dev/null +++ b/vector/src/main/play/listings/kab/short_description.txt @@ -0,0 +1 @@ +Adiwenni aɣellsan ur nelli aslammas & VoIP. Ḥrez isefra-k•m seg tama tis tlata. From 9761566b28e83137f6fe1bfbb62009d5e96b260b Mon Sep 17 00:00:00 2001 From: Imre Kristoffer Eilertsen Date: Wed, 26 Aug 2020 14:50:10 +0000 Subject: [PATCH 078/257] =?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 44.1% (815 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/nb_NO/ --- vector/src/main/res/values-nb-rNO/strings.xml | 253 +++++++++++++++++- 1 file changed, 252 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 d2ab1a8d4f..edd44a1a8c 100644 --- a/vector/src/main/res/values-nb-rNO/strings.xml +++ b/vector/src/main/res/values-nb-rNO/strings.xml @@ -257,7 +257,7 @@ Algoritme Økt-ID Det offentlige navnet til en økt er synlig for folkene du kommuniserer med - ID + Økt-ID Øktnøkkel Verifisering Eksporter @@ -776,4 +776,255 @@ Logg på med single sign-on E-post eller brukernavn Brukernavn + E-postadresse (valgfritt) + Telefonnummer (valgfritt) + Gjenta passord + Bekreft ditt nye passord + Manglende passord + Dette ser ikke ut som en gyldig E-postadresse + Dette ser ikke ut som et gyldig telefonnummer + Manglende E-postadresse + Manglende telefonnummer + Manglende E-postadresse eller telefonnummer + Passordene samsvarer ikke + SSL-feil. + For mange forespørsler har blitt sendt + Send som + Vil du avbryte nedlastingen\? + Vil du avbryte opplastingen\? + Rommets navn + + 1 aktivt medlem + %d aktive medlemmer + + Forlat rommet + %1$s for %2$s siden + + Direktemeldinger + Forlat dette rommet + Fjern fra dette rommet + Utnevn til moderator + Utnevn til admin + Ignorer bruker + Ignorer + + Opphev ignorering + + Bannlys bruker + "%1$s, " + %1$s og %2$s + %1$s og %2$s skriver … + %1$s, %2$s og andre skriver … + Avbryt alle + + 1 ny melding + %d nye meldinger + + + Romdetaljer + + 1 valgt + %d valgte + + INVITERT + MELDINGER + FILER + + Opprett et rom + Bli med i rommet + Bli med i et rom + Betingelser og vilkår + Personvernregler + + Legg til E-postadresse + Legg til telefonnummer + Avanserte varselsinnstillinger + Systeminnstillinger. + Kontoinnstillinger. + Start ved systemoppstart + Skru av restriksjoner + + Batterioptimalisering + Redusert privatliv + Skru på varsler for denne kontoen + Skru på varsler for denne økten + Skru på skjermen i 3 sekunder + Start ved systemoppstart + Betingelser og vilkår + Tøm mediemellomlager + + Brukerinnstillinger + Ignorerte brukere + Integreringer + Vis lesekvitteringer + Send melding med Enter + Administrer + Sett opp på denne enheten + Deaktiver kontoen min + Oppdag + Behandle dine oppdagelsesinnstillinger. + Gi tillatelse + Velg et annet alternativ + + Gi tillatelse + + Datasparingsmodus + Øktinformasjon + Hjemmetjener + Tillat integreringer + Integreringer er skrudd av + Velg språk + + Verifisering avventer + Denne E-postadressen ble ikke funnet. + Oppdater passord + Telefonverifisering + Standardkomprimering + Merket som: + + Tilgang og synlighet + Romtilgang + Punkt-til-punkt-kryptering + Punkt-til-punkt-kryptering er skrudd på + Ugyldig samfunns-ID + Offentlig navn + Offentlig navn + ukjent økt + %1$s i %2$s + %1$s: %2$s + %1$s: %2$s %3$s + + Aktive moduler + + + Last inn modulen på nytt + Bruk kameraet + Bruk mikrofonen + Behandle integreringer + Ingen aktive moduler + Vennligst skriv inn passordet ditt. + Samtalen fortsetter her + Kontakt administrator + + Beklager, det oppstod en feil + + Opprett en passordfrase + Bekreft passordfrasen + Skriv inn passordfrase + Passordfrasen samsvarer ikke + Vennligst skriv inn en passordfrase + Passordfrasen er for svak + + (Avansert) + Velg passordfrase + Suksess! + Gjenopprettingsnøkkel + Skriv inn gjenopprettingsnøkkelen + + Gjenopprett fra sikkerhetskopi + Slett sikkerhetskopien + + Slett sikkerhetskopien + Begynn verifisering + Du bruker ikke noen identitetstjenere + Samtaler + Legg til reaksjon + Meldingen ble slettet + Vis fjernede meldinger + Vis en stattholder for fjernede meldinger + Alle samfunn + + Rom-arkiv + Matrix SDK-versjon + Hurtigreaksjoner + + Send inn et forslag + Krypterer filen … + Navn eller ID (#example:matrix.org) + + Filtrer etter brukernavn eller ID … + + Vis redigeringshistorikk + + MEDIA + FILER + %1$s, kl. %2$s + Det er upassende + IGNORER BRUKER + + Ignorer bruker + + Spoiler + Du ignorerer ikke noen brukere + + Langklikk på et rom for å se flere innstillinger + + + Tilpassede og avanserte innstillinger + + Koble til %1$s + Adresse + Sjekk innboksen din + Telefonnummer (valgfritt) + Bekreft telefonnummer + Registrer deg på %1$s + Brukernavn eller E-postadresse + Det brukernavnet har blitt tatt + Matrix-ID + Du er logget av + Du er logget av + Tøm alle data + + Se alle mine økter + Skru på kryptering + De samsvarer ikke + Klistremerke + + Skru på kryptering + + Oppdater + + Din gjenopprettingsnøkkel + Avslutt + + Kryptering er skrudd på + Kryptering er ikke skrudd på + Medlinger som inneholder @room + Krypterte meldinger i samtaler under fire øyne + Krypterte meldinger i gruppesamtaler + Når rom blir oppgradert + Feilsøk + %1$s (%2$s) + + Velg et nytt kontopassord … + + Ukryptert + Legg til medlemmer + Inviterer brukere … + Inviter brukere + Nåværende språk + Andre tilgjengelige språk + Bruk %1$s + Send + Rolle + Demp mikrofonen + Opphev demping av mikrofonen + Stopp kameraet + Start kameraet + + Sett opp + Rommets navn + Emne + Kan ikke dekryptere + SKJØNNER + LÆR MER + + Telefonkatalogen din er tom + Telefonkatalog + Søk i mine kontakter + Bannlyst av %1$s + Bekreft PIN-kode + Skriv inn PIN-koden din + Glemt PIN-koden\? + Skru på PIN-kode From 1fcb8d712b2a9f526735d71fe33c7ada1d8fede7 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Wed, 26 Aug 2020 15:38:43 +0000 Subject: [PATCH 079/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.7% (1843 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 157 +++++++++--------- 1 file changed, 78 insertions(+), 79 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 493f1f43fa..684c429ec0 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -28,7 +28,7 @@ Link Ver código-fonte Ver código-fonte descriptografado - Excluir + Apagar Renomear Denunciar conteúdo Chamada em andamento @@ -379,9 +379,9 @@ Motivo de denunciar este conteúdo - Você deseja ocultar todas as mensagens deste usuário\?↵ -\n↵ -\nNote que esta ação irá reiniciar o aplicativo e poderá tomar um certo tempo. + Deseja ocultar todas as mensagens deste usuário\? +\n +\nEsta ação irá reiniciar o aplicativo e poderá demorar um pouco. Cancelar envio Cancelar download @@ -423,13 +423,13 @@ Configurações Versão Termos e condições - Avisos de terceiros + Licenças de terceiros Direito autoral Política de privacidade - Imagem do perfil + Foto de perfil Nome e sobrenome E-mail Adicionar endereço de e-mail @@ -442,11 +442,11 @@ Ativar notificações nesta sessão Acender a tela por 3 segundos - Msgs em conversas diretas + Mensagens em conversas individuais Mensagens em salas - Quando eu sou convidado a uma sala - Convites para chamadas - Mensagens enviadas por "bot" + Quando eu for convidada(o) a uma sala + Recebendo chamada + Mensagens enviadas por bots Sincronização em segundo plano Ativar a sincronização em segundo plano @@ -456,12 +456,12 @@ segundos Versão - versão olm + Versão do olm Termos e condições - Avisos de terceiros + Licenças de terceiros Direitos autorais Política de privacidade - Limpar cache + Limpar cache e recarregar @@ -471,7 +471,7 @@ Outros Avançado Criptografia - Alvos de notificação + Aparelhos notificados Contatos locais Permissão de acesso a contatos País da agenda de contatos @@ -492,7 +492,7 @@ Conectado como Servidor Principal (Home Server) - Servidor de Identidade (Identity Server) + Servidor de identidade Confirmação pendente Por favor, verifique o seu e-mail e clique no link que está lá. Feito isso, clique em continuar. @@ -502,9 +502,9 @@ Este endereço de e-mail não foi encontrado. Este número de telefone já está em uso. - Alterar a senha + Alterar senha Senha atual - Senha nova + Nova senha Confirme a nova senha Não consegui atualizar a senha Sua senha foi atualizada @@ -600,7 +600,7 @@ Diretório - %s estava tentando carregar um ponto específico da linha do tempo desta sala, mas não conseguiu encontrá-lo. + %s tentou carregar um trecho específico da conversa desta sala, mas não conseguiu. @@ -685,7 +685,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Mostrar a hora para todas as mensagens Modo de economia de dados - Interface de usuária(o) + Aparência Idioma Escolha o idioma @@ -747,7 +747,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Som de notificação Mensagens que contenham o meu nome e sobrenome - Mensagens que contenham o meu nome de usuária(o) + Mensagens que contenham o meu nome de usuário Visualização prévia do endereço Mostrar a hora no formato de 12 horas Vibrar ao mencionar um usuário @@ -987,7 +987,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Define a descrição da sala Remove o usuário com o ID fornecido Altera o seu nome e sobrenome - Ativar/Desativar o Markdown + Ativar/Desativar a formatação de texto Reparar a gestão de aplicativos Matrix @@ -1049,46 +1049,46 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Motivo Versão %s - Notificações de Resolução de Problemas - Diagnóstico de Resolução de Problemas + Resolver problemas nas notificações + Diagnóstico de resolução de problemas Executar Testes Executando… (%1$d of %2$d) - Diagnóstico básico está ok. Se você ainda não recebe notificações, por favor relate um erro para nos ajudar a investigar. + O diagnóstico básico está ok. Se você ainda não recebe notificações, por favor relate um erro para nos ajudar a investigar. Um ou mais testes falharam, tente as correções sugeridas. Um ou mais testes falharam, por favor relate um erro para nos ajudar a investigar. - Configurações do sistema. + Configurações do sistema Notificações estão ativadas nas configurações do sistema. Notificações estão desativadas nas configurações do sistema. Por favor, revise as configurações do sistema. Abra as Configurações - Configurações da Conta. + Configurações da conta Notificações estão ativadas para sua conta. Notificações estão desativadas para sua conta.↵ \nPor favor, revise as configurações da conta. Ativar - Configurações da sessão. + Configurações da sessão Notificações estão ativadas nesta sessão. Remover da sala Notificações não estão ativadas nesta sessão.↵ \nPor favor, revise as configurações do Element. Ativar - Revisão do Play Services + Versão do Google Play Services Google Play Services APK está disponível e atualizado. Element usa Google Play Services para entregar mensagens push, mas isto não parece está configurado corretamente: %1$s Consertar Play Services - Token Firebase + Token do Firebase Token FCM recuperado com sucesso: %1$s Ligar mesmo assim Falha ao recuperar o token do FCM: %1$s - Registro de Token + Registro do token do Firebase Token FCM registrado com sucesso no HomeServer. Falha ao registrar o token FCM no HomeServer: %1$s @@ -1118,8 +1118,8 @@ Tente reiniciar a aplicação. Prévia de links dentro do chat quando seu homeserver suporta este recurso. Permitir que saibam quando eu estiver digitando Deixe outros usuários saberem quando você estiver digitando. - Mostrar confirmações de leitura - Clique nas notificações de leitura para uma lista detalhada. + Mostrar confirmações de leitura dos outros usuários + Clique nas confirmações de leitura para obter mais informações. Mostrar eventos de entrada e saída de sala Convites, remoções e banimentos não são afetados. Mostrar eventos da conta @@ -1132,8 +1132,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Restrições em segundo plano estão ativadas para o Element.↵ \nO aplicativo funciona bastante restringido enquanto está em segundo plano, o que pode afetar as notificações.↵ \n%1$s - Formatação Markdown - Fomatar mensagens usando a sintaxe markdown antes delas serem enviadas. Isto permite uma formatação avançada como usar asteriscos para mostrar texto em itálico. + Formatação de texto + Formatar o texto das mensagens a serem enviadas. Por exemplo: inserir asteriscos antes e depois do texto, mostrará o texto em itálico. Conceder permissão Ocorreu um erro ao confirmar seu endereço de e-mail. @@ -1143,11 +1143,11 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Informação adicional: %s Inicie a câmera do sistema em vez da câmera personalizada. - Esta opção requer um aplicativo de terceiros para gravar as mensagens. + Esta opção requer um aplicativo de terceiros para gravar mensagens de voz. O comando \"%s\" precisa de mais parâmetros ou alguns parâmetros estão incorretos. - Markdown foi ativado. - Markdown foi desativado. + A formatação de texto foi ativada. + A formatação de texto foi desativada. Aumente o desempenho apenas carregando os membros da sala na primeira exibição. Seu homeserver não suporta o carregamento Lazy de membros da sala ainda. Tente depois. @@ -1197,10 +1197,10 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Abortar Deseja mesmo sair\? - Configurações avançadas de notificações - Importância da notificação por evento + Configurar notificações + Configurar notificações por evento - Configurações personalizadas. + Configurações personalizadas Observe que alguns tipos de mensagens estão configurados para serem silenciosos (produzirão uma notificação sem som). Algumas notificações estão desativadas nas suas configurações personalizadas. Falha ao carregar regras personalizadas, tente novamente. @@ -1285,7 +1285,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Chamada em andamento (%s) Retornar à chamada - Adicionar um servidor de identidade nas suas configurações para executar esta ação. + Adicione um servidor de identidade nas suas configurações para executar esta ação. Cancelar convite Reduzir privilégios\? Você não poderá desfazer essa alteração, já que está reduzido seus privilégios. Se você for a última pessoa nesta sala, será impossível recuperar a permissão atual. @@ -1293,8 +1293,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Bloquear usuário - Ao bloquear este usuário, as mensagens dele serão ocultadas de você em todas as salas.↵ -\n↵ + Ao bloquear este usuário, as mensagens dele serão ocultadas de você em todas as salas. +\n \nVocê pode reverter esta ação a qualquer momento nas configurações. Desbloquear usuário Desbloquear este usuário mostrará todas as mensagens dele novamente. @@ -1332,9 +1332,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr %s↵ \nA sincronização pode ser adiada dependendo dos recursos (bateria) ou do estado do aparelho (modo de suspensão). Integrações - Use o Gerenciador de Integrações para gerenciar bots, pontes, widgets e pacotes de figurinhas.↵ -\n -\nO Gerenciador de Integrações recebe dados de configuração e pode modificar widgets, enviar convites para salas e definir níveis de privilégios em seu nome. + Use o Gerenciador de Integrações para gerenciar bots, pontes, widgets e pacotes de figurinhas. +\nO Gerenciador de Integrações recebe dados de configuração e pode modificar widgets, enviar convites para salas e definir níveis de permissão em seu nome. Botão enter do teclado enviará a mensagem em vez de adicionar uma quebra de linha Backup Seguro @@ -1644,7 +1643,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Contato não corresponde Erro Desconhecido - Você não está usando nenhum Servidor de Identidade + Você não está usando algum servidor de identidade Nenhum servidor de identidade está configurado. É necessário usar um para redefinir sua senha. Parece que você está tentando se conectar com outro servidor local. Deseja sair\? @@ -1673,10 +1672,10 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Veja as reações Reações - Mensagens excluídas - Mostrar mensagens excluídas - Mostrar um espaço reservado para mensagens excluídas - Evento excluído pelo usuário + Mensagem apagada + Mostrar mensagens apagadas + Mostrar um espaço reservado para mensagens apagadas + Evento apagado pelo usuário Evento moderado pelo administrador da sala Última edição por %1$s em %2$s @@ -1708,8 +1707,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Importar as chaves de arquivo \"%1$s\". - Versão SDK de Matrix - Outros avisos de terceiros + Versão do SDK da Matrix + Outras licenças de terceiros Você já está vendo esta sala! Reações rápidas @@ -1741,7 +1740,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Obrigado, a sugestão foi enviada com êxito A sugestão não foi enviada (%s) - Mostrar eventos ocultos na linha do tempo + Mostrar eventos ocultos nas conversas Conversas @@ -1768,7 +1767,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Nome ou ID (#example:matrix.org) Ativar o recurso de deslizar para responder nas conversas - Merge não conseguiu decifrar a mensagem na linha do tempo + Alertar apenas uma vez em uma conversa de que não é possível descriptografar as mensagens, em vez de alertar para cada mensagem Adicione uma aba dedicada para notificações não lidas na tela principal. Link copiado para a memória @@ -1794,7 +1793,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Servidor de identidade Desconectar servidor de identidade Configurar servidor de identidade - Alterar o servidor de identidade + Alterar servidor de identidade Atualmente você está usando %1$s para descobrir e ser descoberto pelos contatos existentes. No momento, você não está usando um servidor de identidade. Para descobrir e ser descoberto pelos contatos existentes, adicione um abaixo. Endereços de e-mail detectáveis @@ -1817,7 +1816,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Atualmente, você está compartilhando endereços de e-mail ou números de telefone no servidor de identidade %1$s. Você precisará reconectar-se a %2$s para parar de compartilhá-los. Concorde com os Termos de Serviço do servidor de identidade (%s), para que você possa ser descoberto por endereço de e-mail ou por número de telefone. - Ativar registros detalhados. + Ativar registros detalhados Os registros detalhados ajudarão os desenvolvedores, ao fornecerem mais registros quando você usar sacudir o aparelho. Mesmo quando ativado, o aplicativo não registra o conteúdo da mensagem ou qualquer outro dado privado. @@ -1905,7 +1904,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Estraga-Surpresa Digite palavras-chave para encontrar uma reação. - Você não está bloqueando nenhum usuário + Nenhum usuário bloqueado Clique longo sobre uma sala para ver mais opções @@ -1928,7 +1927,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Hospedagem Premium para organizações Saiba mais Outros - Configurações personalizadas + Configurações avançadas e preferências Continuar Conecte-se a %1$s @@ -1961,7 +1960,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Um e-mail de confirmação será enviado para sua caixa de entrada, para você confirmar a definição de sua nova senha. Próximo E-mail - Senha nova + Nova senha Atenção! Alterar a sua senha redefinirá todas as chaves de criptografia de ponta a ponta existentes em todas as suas sessões, tornando o histórico de mensagens criptografadas ilegível. Faça uma cópia (backup) das suas chaves, ou exporte as chaves de outra sessão antes de alterar a sua senha. @@ -2086,7 +2085,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Veja todas as minhas sessões Configurações avançadas Modo desenvolvedor - O modo desenvolvedor ativa características ocultas e pode também tornar o aplicativo menos estável. Somente para desenvolvedores! + O modo de desenvolvedor permite ativar recursos ocultos, o que pode tornar o aplicativo menos estável. Somente para desenvolvedores! Agitar celular Detectar patamar Agite seu telefone para testar o limiar de detecção @@ -2098,7 +2097,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Mostrando apenas os primeiros resultados, digite mais letras… Relatar imediatamente as falhas - Element pode quebrar com mais freqüência quando ocorre um erro inesperado + Element poderá quebrar com mais frequência quando ocorrer um erro inesperado Adicionar ¯\\_(ツ)_/¯ para uma mensagem de texto simples @@ -2204,9 +2203,9 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Envia a mensagem colorida como arco-íris Envia o emoji colorido como um arco-íris - Linha do Tempo + Conversas - Editor de mensagens + Campo de texto Ativar a criptografia de ponta a ponta Uma vez ativada, a criptografia não poderá ser desativada. @@ -2224,12 +2223,12 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Sua nova sessão agora está confirmada. Ela tem acesso às suas mensagens criptografadas, e outros usuários a verão como confirmada. Autoverificação - A autoverificação está ativada↵ + A autoverificação está ativada \nChaves privadas estão no aparelho. - A autoverificação está ativada↵ -\nAs chaves são confiáveis.↵ + A autoverificação está ativada +\nAs chaves são confiáveis. \nAs chaves privadas não são conhecidas - A autoverificação está ativada.↵ + A autoverificação está ativada. \nAs chaves não são confiáveis A autoverificação não está ativada @@ -2307,9 +2306,9 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Excluír… Deseja enviar este anexo para %1$s\? - Enviar imagem do tamanho original - Enviar imagens do tamanho original - + Enviar imagem no tamanho original + Enviar imagens no tamanho original + Confirmar a exclusão Tem certeza de que deseja apagar este evento\? Observe que, se você apagar a alteração do nome ou descrição de uma sala, isso reverterá a alteração. @@ -2429,12 +2428,12 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Falha na importação de chaves Mensagens contendo @room - Mensagens criptografadas em bate-papos individuais - Mensagens criptografadas em conversas em grupo - Quando as salas são atualizadas - Definir a importância da notificação por evento + Mensagens criptografadas em conversas individuais + Mensagens criptografadas em salas + Quando a versão da sala é atualizada + Ajustar as notificações por evento - Envia uma mensagem como texto simples, sem interpretá-la como markdown + Envia uma mensagem como texto simples, sem formatar o texto Nome de usuário e/ou senha incorretos. A senha digitada começa ou termina com espaços, favor verificá-la. Esta conta foi desativada. @@ -2460,7 +2459,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Não conheça sua Frase Secreta de Chave do Backup, você pode %s. Chave de recuperação de Chave do Backup - Impedir captura da tela do aplicativo + Impedir a captura de tela do aplicativo Ativando esta opção acrescenta FLAG_SECURE a todas as atividades. Reinicie o aplicativo para que a alteração tenha efeito. Arquivo de mídia adicionado à Galeria @@ -2521,7 +2520,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Carregando os idiomas disponíveis… Abra termos de %s - Desconectar do servidor de identidade %s\? + Desconectar-se do servidor de identidade %s\? Este servidor de identidade está desatualizado. Element suporta apenas API V2. Esta operação não é possível. O servidor doméstico está desatualizado. Por favor, primeiro configure um servidor de identidade. @@ -2534,7 +2533,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Use %1$s Como alternativa, você pode digitar o endereço de outro servidor de identidade Digite o endereço de um servidor de identidade - Submeter + Enviar Definir o papel Papel Bate-papo aberto From 8372c9e3edad6ce8b7eeba63b3cd3cb1e33328aa Mon Sep 17 00:00:00 2001 From: aevw Date: Wed, 26 Aug 2020 20:31:47 +0000 Subject: [PATCH 080/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.7% (1843 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 684c429ec0..3fab804498 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -617,7 +617,7 @@ Informação sobre a sessão do remetente Nome público do aparelho Nome - ID do aparelho + ID da Sessão Chave da sessão Confirmação Impressão digital ed25519 @@ -2615,4 +2615,24 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Confirme o PIN para desativar o PIN Evitar chamadas acidentais Confirmarei a intenção de iniciar uma chamada - +Você não tem permissão para iniciar uma teleconferência nesta sala + Uma conferência já está em andamento! + Iniciar reunião em vídeo + Iniciar reunião de áudio + As reuniões utilizam as políticas de segurança e permissão de Jitsi. Todas as pessoas que estão atualmente na sala verão um convite para participar enquanto sua reunião está acontecendo. + Você não pode iniciar uma chamada com você mesmo + Você não pode iniciar uma chamada consigo mesmo, esperar que os participantes aceitem o convite + Falha ao adicionar widget + Falha ao remover widget + + %1$d/%2$d chave importada com êxito. + %1$d/%2$d chaves importadas com êxito. + + + Gerenciar integrações + Sem widgets ativos + A sala foi criada, mas alguns convites não foram enviados pelo seguinte motivo: +\n +\n%s + + From 90e580245a180f2658bac5f0780e3388340a26df Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Wed, 26 Aug 2020 20:37:17 +0000 Subject: [PATCH 081/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (235 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/pt_BR/ --- matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml b/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml index e1b99506c8..6346bf2cf4 100644 --- a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml +++ b/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml @@ -124,10 +124,10 @@ Você removeu a descrição da sala %1$s removeu a foto da sala Você removeu a foto da sala - Mensagem removida - Mensagem removida por %1$s - Mensagem removida [motivo: %1$s] - Mensagem removida por %1$s [motivo: %2$s] + Mensagem apagada + Mensagem apagada por %1$s + Mensagem apagada [motivo: %1$s] + Mensagem apagada por %1$s [motivo: %2$s] Você atualizou o seu perfil %1$s Você enviou um convite para %1$s entrar na sala %1$s cancelou o convite a %2$s para entrar na sala From ae81ea2bbc440a569e10c91ac44e3aa6b559ac46 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Tue, 25 Aug 2020 17:28:21 +0000 Subject: [PATCH 082/257] Translated using Weblate (Swedish) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 472c6cfe96..fb0bff1788 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -660,7 +660,7 @@ Aviseringsmål Skicka \"skriver\"-statusar Formatera meddelanden med Markdown-syntax innan de skickas. Detta tillåter avancerad formatering som att använda asterisker för att visa kursiv text. - Visa tidpunkt för alla meddelanden + Visa tidsstämplar för alla meddelanden Visa när folk går med och lämnar Förhandsgranska media innan den skickas Inaktivera konto @@ -1576,7 +1576,7 @@ Hemskärm Inbäddade URL-förhandsgranskningar Förhandsgranska länkar i chatten om din hemserver stöder den här funktionen. - Visa tidpunkter i 12-timmarsformat + Visa tidsstämplar i 12-timmarsformat Inbjudningar, utsparkningar och bann påverkas inte. Visa kontohändelser Vibrera när en användare nämns From 87a97bc8ec5217b20a33c6f9e91834bd68134efd Mon Sep 17 00:00:00 2001 From: vejetaryenvampir Date: Tue, 25 Aug 2020 12:46:06 +0000 Subject: [PATCH 083/257] Translated using Weblate (Turkish) Currently translated at 64.4% (1191 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/tr/ --- vector/src/main/res/values-tr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index 91056b7193..98638c7226 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -126,7 +126,7 @@ Mümkünse, lütfen yapacağınız açıklamayı İngilizce yazın. Sorununu buraya yaz Sorunları teşhis etmek için bu istemciden gelen sistem günlüğü (log) hata raporu ile gönderilecek. Bu hata raporu -sistem günlüğü ve ekran görüntülere dahil- halka açık bir şekilde görünür olmayacaktır. Eğer sadece alttaki yazıları göndermek istiyorsanız, lütfen şunun işaretini kaldırın: - Telefonunu öfkeyle ile sallıyor gibi görünüyorsun. Hata raporu göndermek ister misin\? + Telefonunu yılgınlıkla sallıyor gibi görünüyorsun. Hata raporu göndermek ister misin\? Uygulama en son çökmüştü, hata raporu göndermek ister misiniz\? Hata bildirmek için öfkeyle salla From eddc681d64eb22630de1d737a4e913c76c708ac3 Mon Sep 17 00:00:00 2001 From: strix aluco Date: Tue, 25 Aug 2020 17:12:05 +0000 Subject: [PATCH 084/257] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3 of 3 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.riot.im/projects/element-android/element-store/uk/ --- vector/src/main/play/listings/uk/full_description.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/play/listings/uk/full_description.txt b/vector/src/main/play/listings/uk/full_description.txt index f0e53e4a0f..ca6b4c2ae1 100644 --- a/vector/src/main/play/listings/uk/full_description.txt +++ b/vector/src/main/play/listings/uk/full_description.txt @@ -9,7 +9,7 @@ Element ґрунтовно відрізняється від інших заст Element дозволяє вам розміщувати сервер в себе або обирати будь-якого з надавачів послуг, таким чином забезпечуючи вам конфіденційність і можливість володіти власними даними й бесідами та контролювати їх. Він надає вам доступ до відкритої мережі, тож ви не є обмеженими спілкуванням виключно з користувачами Element. І він є дуже надійним та безпечним. -Element здатен забезпечити усе завдяки тому, що він заснований на протоколі Matrix — стандарті для відкритого та децентралізованого спілкування. +Element здатен забезпечити усе це завдяки тому, що він заснований на протоколі Matrix — стандарті для відкритого та децентралізованого спілкування. Element надає вам повний контроль, дозволяючи обирати з-поміж надавачів послуг, що обслуговують сервери з вашими бесідами. Ви вільні обрати будь-який спосіб розміщення прямо з застосунку Element: From d8a0142aee50735ca9f539e8fc0989ceae0bb923 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Wed, 26 Aug 2020 20:42:48 +0000 Subject: [PATCH 085/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.9% (1848 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 117 +++++++++--------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 3fab804498..d63331c336 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -9,7 +9,7 @@ Mensagens Sala Configurações - Detalhes dos membros + Detalhes do participante Histórico @@ -32,8 +32,8 @@ Renomear Denunciar conteúdo Chamada em andamento - Chamada em grupo em andamento.↵ -\nEntre como %1$s ou %2$s + Chamada em grupo em andamento. +\nEntre com %1$s ou %2$s Voz Vídeo Não foi possível iniciar a chamada, tente mais tarde @@ -275,7 +275,7 @@ Continuar - Remover + Apagar Entrar Visualizar Recusar @@ -294,12 +294,12 @@ Nova conversa Adicionar uma pessoa - 1 integrante + 1 participante - Deixar a sala + Sair da sala Tem certeza de que deseja sair da sala\? - Você tem certeza que quer remover %s desta conversa? + Deseja remover %s desta conversa\? Criar Online @@ -312,7 +312,7 @@ SESSÕES Convidar - Deixar esta sala + Sair da sala Remover desta sala Banir da sala Remover banimento @@ -373,7 +373,7 @@ Pessoas Arquivos Configurações - ID mal formatado. Precisa ser um endereço de e-mail ou um ID Matrix, como \'@membrolocal:dominio\' + ID mal formatado. Precisa ser um endereço de e-mail ou um ID Matrix, como \'@participantelocal:dominio\' CONVIDADOS ENTRARAM @@ -387,7 +387,7 @@ Pesquisar - Filtrar integrantes da sala + Pesquisar participantes da sala Nenhum resultado SALAS MENSAGENS @@ -415,7 +415,7 @@ Favoritar Despriorizar Conversa direta - Deixar a conversa + Sair da conversa Esquecer @@ -512,9 +512,9 @@ \n↵ \nNote que esta ação irá reiniciar o aplicativo e pode levar algum tempo. - Você tem certeza que quer remover este destino de notificação? + Deseja deixar de notificar este aparelho\? - Você tem certeza que quer remover o %1$s %2$s? + Deseja remover o %1$s %2$s\? Escolha um país @@ -552,9 +552,9 @@ Qualquer pessoa - Apenas integrantes (a partir do momento em que esta opção foi escolhida) - Apenas integrantes (desde que foram convidados) - Apenas integrantes (desde que entraram na sala) + Apenas participantes (a partir do momento em que esta opção foi escolhida) + Apenas participantes (desde que foram convidados) + Apenas participantes (desde que entraram na sala) Para fazer um link para uma sala, ela precisa ter um endereço. @@ -658,10 +658,10 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado. Esta sala contém sessões desconhecidas - Esta sala contém sessões desconhecidas que não foram confirmadas.↵ -\nIsso significa que não há garantia de que estas sessões realmente pertencem aos usuários identificados.↵ -\nRecomendamos que você faça o processo de confirmação para cada sessão desconhecida antes de continuar, mas você pode reenviar a mensagem sem confirmar os aparelhos, se preferir.↵ -\n↵ + Esta sala contém sessões desconhecidas que não foram confirmadas. +\nIsso significa que não há garantia de que estas sessões realmente pertencem aos usuários identificados. +\nRecomendamos que você faça o processo de confirmação para cada sessão desconhecida antes de continuar, mas você pode reenviar a mensagem sem confirmar os aparelhos, se preferir. +\n \nSessões desconhecidas nesta sala: @@ -818,7 +818,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Salas Entrou em que foi convidada/o - Filtrar integrantes da comunidade + Pesquisar participantes da comunidade Filtrar salas da comunidade O(A) administrador(a) desta comunidade não definiu uma descrição longa da mesma. @@ -832,13 +832,13 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.Abrir cabeçalho Sincronizando… - %d membro ativo - %d membros ativos - + %d participante ativo + %d participantes ativos + - %d membro - %d membros - + %d participante + %d participantes + %d nova mensagem %d novas mensagens @@ -857,7 +857,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.%d alterações na filiação - Lista de integrantes + Lista de participantes %d mensagem notificada não lida %d mensagens notificadas não lidas @@ -1008,7 +1008,7 @@ Atenção: este arquivo poderá ser apagado se o aplicativo for desinstalado.não faz com que, por padrão, suas mensagens enviadas sejam apagadas. Se você deseja que suas mensagens também sejam apagadas, marque a opção abaixo.↵ \n↵ \nA visibilidade de mensagens na Matrix é semelhante a um e-mail. O fato de apagarmos suas mensagens significa que suas mensagens enviadas não serão compartilhadas com nenhum usuário novo ou ainda não registrado, mas os usuários registrados que já tiveram acesso a essas mensagens ainda terão acesso uma cópia delas. - Quando minha conta for desativada, exclua todas as mensagens que eu enviei (Atenção: isso fará com que futuros usuários tenham uma visão incompleta das conversas) + Quando minha conta for desativada, apague todas as mensagens que eu enviei (Atenção: isso fará com que futuros usuários tenham uma visão incompleta das conversas) Para continuar, entre com sua senha: Desativar minha conta @@ -1149,8 +1149,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr A formatação de texto foi ativada. A formatação de texto foi desativada. - Aumente o desempenho apenas carregando os membros da sala na primeira exibição. - Seu homeserver não suporta o carregamento Lazy de membros da sala ainda. Tente depois. + Aumente o desempenho apenas carregando os participantes da sala na primeira exibição. + Seu servidor principal ainda não suporta o carregamento Lazy de participantes da sala. Tente depois. Desculpe, ocorreu um erro @@ -1171,7 +1171,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Se um usuário deixar um aparelho desconectado por um período de tempo, com a tela desligada, o aparelho entrará no modo Soneca. Isso impede que os aplicativos acessem a rede, adiando seus trabalhos, sincronizações e alarmes padrão. Criar frase secreta A frase secreta está errada - Carregamento Lazy dos membros das salas + Carregamento Lazy dos participantes das salas Chamada de vídeo em andamento… @@ -1251,8 +1251,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Pronto Notificações - Peça ao administrador do seu servidor principal (%1$s) que configure um servidor TURN para que as chamadas funcionem de maneira confiável.↵ -\n↵ + Peça ao administrador do seu servidor principal (%1$s) que configure um servidor TURN para que as chamadas funcionem de maneira confiável. +\n \nAlternativamente, você pode tentar usar o servidor público em %2$s. No entanto, ele não é tão confiável e compartilhará o seu IP com esse servidor. Você também pode configurar isso nas Configurações. Tente usar %s Não pergunte novamente @@ -1302,8 +1302,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Tem certeza que quer cancelar o convite para este usuário\? Remover usuário Motivo da remoção - esta ação removerá o usuário desta sala.↵ -\n↵ + esta ação removerá o usuário desta sala. +\n \nPara impedir que o usuário nunca mais entre novamente, você precisará bani-lo. Banir usuário Motivo do banimento @@ -1560,8 +1560,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Excluir as chaves de criptografia do servidor\? Você não será mais capaz de usar a sua chave de recuperação para ler o histórico de mensagens criptografadas. Novo Backup da Chave - Foi detectado um novo backup da chave de mensagem.↵ -\n↵ + Foi detectado um novo backup da chave de mensagem. +\n \nSe você não definiu o novo método de recuperação, um invasor pode estar tentando acessar sua conta. Altere a senha da sua conta e defina um novo método de recuperação imediatamente nas Configurações. Foi eu @@ -1638,7 +1638,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr O compromisso de hash não coincidiu O SAS não corresponde A sessão recebeu uma mensagem inesperada - Foi recebida uma mensagem inválida + Uma mensagem inválida foi recebida Chave incorreta Contato não corresponde Erro Desconhecido @@ -1856,10 +1856,10 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Não conseguia lidar com dados compartilhados MÍDIA - Não há mídia nesta sala + Nenhuma mídia nesta sala ARQUIVOS %1$s em %2$s - Não há arquivos nesta sala + Nenhum arquivo nesta sala É spam É inapropriado @@ -1886,7 +1886,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr \n↵ \nPermita o acesso na próxima janela para poder exportar suas chaves manualmente. - Não há conexão de rede neste momento + Não há conexão de rede no momento Bloqueia usuário @@ -1896,7 +1896,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Silenciar Configurações Adicionar aos favoritos - Excluír dos favoritos + Remover dos favoritos Sair da sala %1$s não fez nenhuma alteração Você não fez nenhuma alteração @@ -2047,12 +2047,12 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Lida por Você está desconectada/o - Isso pode ser devido à vários motivos:↵ -\n↵ -\n• Você alterou sua senha em outra sessão.↵ -\n↵ -\n• Você excluiu esta sessão de outra sessão.↵ -\n↵ + Isso pode ser devido à vários motivos: +\n +\n• Você alterou sua senha em outra sessão. +\n +\n• Você excluiu esta sessão de outra sessão. +\n \n• O administrador do seu servidor invalidou seu acesso por motivos de segurança. Entrar novamente @@ -2158,9 +2158,9 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr \n↵ \nPara máxima segurança, faça isso pessoalmente. As mensagens nesta sala não estão criptografadas de ponta a ponta. - As mensagens nesta sala são criptografadas de ponta a ponta.↵ -\n↵ -\nSuas mensagens são protegidas com cadeados e somente você e o destinatário têm as chaves exclusivas que permitam a sua leitura. + As mensagens nesta sala estão criptografadas de ponta a ponta. +\n +\nSuas mensagens estão protegidas com cadeados e somente você e o destinatário têm as chaves exclusivas que permitem a leitura delas. Segurança Saiba mais Mais @@ -2171,8 +2171,8 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Uma pessoa %1$d pessoas - Subidas - Deixar a sala + Mídia e arquivos + Sair da sala Deixando a sala… Administradores @@ -2303,7 +2303,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Atenção: Você só deveria entrar no armazenamento secreto a partir de um aparelho confiável - Excluír… + Apagar Deseja enviar este anexo para %1$s\? Enviar imagem no tamanho original @@ -2315,7 +2315,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Incluir o motivo Motivo da edição - Evento excluído pelo usuário, motivo: %1$s + Evento apagado pelo usuário, motivo: %1$s Evento moderado pelo administrador da sala, motivo: %1$s As chaves já estão atualizadas! @@ -2401,7 +2401,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Configuração de notificações Solução de problemas - Mensagem… + Digite uma mensagem… Use Arquivo @@ -2410,7 +2410,6 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Verificando a chave de backup Criando uma Frase Secreta de Recuperação permite proteger e desbloquear mensagens criptografadas e estabelecer confiança. \n -\n \nSe você não quiser definir uma Senha de Mensagem, crie antes uma Chave de Mensagem. Criar uma Frase Secreta de Recuperação permite proteger e desbloquear mensagens criptografadas e estabelecer confiança. Se você cancelar agora, poderá perder mensagens e dados criptografados para sempre se esquecer seus credenciais. @@ -2503,7 +2502,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Não foi possível criar sua DM. Por favor, verifique os usuários que você deseja convidar e tente novamente. - Adicionar membros + Adicionar participantes CONVITE Convidando os usuários… Convidar Usuários From 7657c0f905a19442f083f2b3bcf0261685e15fac Mon Sep 17 00:00:00 2001 From: aevw Date: Wed, 26 Aug 2020 20:44:51 +0000 Subject: [PATCH 086/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.9% (1848 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index d63331c336..08bd5f906e 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -254,8 +254,6 @@ Element necessita permissão para acessar seu microfone para realizar chamadas de áudio. " \n -\n↵ -\n↵ \nPor favor, permita o acesso na próxima tela para fazer a chamada." Element necessita permissão para acessar sua câmera e seu microfone para fazer chamadas de vídeo.↵ \n↵ @@ -1867,7 +1865,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Denunciar conteúdo Motivo para denúnciar este conteúdo RELATÓRIO - BLOQUEAR USUÁRIO + IGNORAR USUÁRIO Conteúdo relatado Este conteúdo foi relatado. @@ -1888,7 +1886,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Não há conexão de rede no momento - Bloqueia usuário + Ignorar usuário Todas as mensagens novas (com som) Todas as mensagens novas @@ -2634,4 +2632,14 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr \n \n%s + + %1$s, %2$s e %3$d um outro leu + %1$s, %2$s e %3$d outros leram + + + Código errado, %d tentativa restante + Código errado, %d tentativas restantes + + Advertência! Última tentativa restante antes de logout! + Demasiados erros, você foi desconectado From 9c1c9f96e192953e129198aecf6dde436164b216 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 27 Aug 2020 10:34:40 +0200 Subject: [PATCH 087/257] Room v6: finish cleaning up --- matrix-sdk-android/build.gradle | 2 - .../sdk/internal/network/RetrofitFactory.kt | 4 +- .../sdk/internal/session/room/RoomAPI.kt | 15 -------- .../room/relation/DefaultRelationService.kt | 2 +- .../session/room/send/EncryptEventWorker.kt | 9 +++-- .../MultipleEventSendingDispatcherWorker.kt | 2 +- .../session/room/send/RoomEventSender.kt | 2 +- .../session/room/send/SendEventWorker.kt | 37 ++++++++----------- 8 files changed, 25 insertions(+), 48 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index d70b0bbe84..90bdf02243 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -131,8 +131,6 @@ dependencies { // Network implementation "com.squareup.retrofit2:retrofit:$retrofit_version" implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version" - implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" - implementation(platform("com.squareup.okhttp3:okhttp-bom:4.8.1")) implementation 'com.squareup.okhttp3:okhttp' diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitFactory.kt index 368611dd7d..89a0ce597a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/RetrofitFactory.kt @@ -19,13 +19,12 @@ package org.matrix.android.sdk.internal.network import com.squareup.moshi.Moshi import dagger.Lazy -import org.matrix.android.sdk.internal.util.ensureTrailingSlash import okhttp3.Call import okhttp3.OkHttpClient import okhttp3.Request +import org.matrix.android.sdk.internal.util.ensureTrailingSlash import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory -import retrofit2.converter.scalars.ScalarsConverterFactory import javax.inject.Inject internal class RetrofitFactory @Inject constructor(private val moshi: Moshi) { @@ -50,7 +49,6 @@ internal class RetrofitFactory @Inject constructor(private val moshi: Moshi) { return okHttpClient.get().newCall(request) } }) - .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(UnitConverterFactory) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 25dcc69fa8..d8df86be8f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -130,21 +130,6 @@ internal interface RoomAPI { @Body content: Content? ): Call - /** - * Send an event to a room. - * - * @param txId the transaction Id - * @param roomId the room id - * @param eventType the event type - * @param content the event content as string - */ - @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send/{eventType}/{txId}") - fun send(@Path("txId") txId: String, - @Path("roomId") roomId: String, - @Path("eventType") eventType: String, - @Body content: String? - ): Call - /** * Get the context surrounding an event. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt index 2199193de0..111551d66d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt @@ -208,7 +208,7 @@ internal class DefaultRelationService @AssistedInject constructor( } private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest { - val sendContentWorkerParams = SendEventWorker.Params(sessionId, event) + val sendContentWorkerParams = SendEventWorker.Params(sessionId = sessionId, event = event) val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) return timeLineSendEventWorkCommon.createWork(sendWorkData, startChain) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/EncryptEventWorker.kt index d23835e838..f878df52b2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/EncryptEventWorker.kt @@ -120,7 +120,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) localEchoRepository.updateEncryptedEcho(localEvent.eventId, safeResult.eventContent, decryptionLocalEcho) } - val nextWorkerParams = SendEventWorker.Params(params.sessionId, encryptedEvent) + val nextWorkerParams = SendEventWorker.Params(sessionId = params.sessionId, event = encryptedEvent) return Result.success(WorkerParamsFactory.toData(nextWorkerParams)) } else { val sendState = when (error) { @@ -129,8 +129,11 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) } localEchoRepository.updateSendState(localEvent.eventId, sendState) // always return success, or the chain will be stuck for ever! - val nextWorkerParams = SendEventWorker.Params(params.sessionId, localEvent, error?.localizedMessage - ?: "Error") + val nextWorkerParams = SendEventWorker.Params( + sessionId = params.sessionId, + event = localEvent, + lastFailureMessage = error?.localizedMessage ?: "Error" + ) return Result.success(WorkerParamsFactory.toData(nextWorkerParams)) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt index 73791e8412..ead2dc9377 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt @@ -105,7 +105,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo } private fun createSendEventWork(sessionId: String, event: Event, startChain: Boolean): OneTimeWorkRequest { - val sendContentWorkerParams = SendEventWorker.Params(sessionId, event) + val sendContentWorkerParams = SendEventWorker.Params(sessionId = sessionId, event = event) val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) return timelineSendEventWorkCommon.createWork(sendWorkData, startChain) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RoomEventSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RoomEventSender.kt index 65c692f42e..e46adeb9c1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RoomEventSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/RoomEventSender.kt @@ -65,7 +65,7 @@ internal class RoomEventSender @Inject constructor( } private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest { - val sendContentWorkerParams = SendEventWorker.Params(sessionId, event) + val sendContentWorkerParams = SendEventWorker.Params(sessionId = sessionId, event = event) val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) return timelineSendEventWorkCommon.createWork(sendWorkData, startChain) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt index d37b5e90c2..5da14f0a41 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/SendEventWorker.kt @@ -47,22 +47,11 @@ internal class SendEventWorker(context: Context, @JsonClass(generateAdapter = true) internal data class Params( override val sessionId: String, + override val lastFailureMessage: String? = null, val event: Event? = null, - val eventId: String? = null, - val roomId: String? = null, - val type: String? = null, - override val lastFailureMessage: String? = null - ) : SessionWorkerParams { - - constructor(sessionId: String, event: Event, lastFailureMessage: String? = null) : this( - sessionId = sessionId, - eventId = event.eventId, - roomId = event.roomId, - type = event.type, - event = event, - lastFailureMessage = lastFailureMessage - ) - } + // Keep for compat at the moment, will be removed later + val eventId: String? = null + ) : SessionWorkerParams @Inject lateinit var localEchoRepository: LocalEchoRepository @Inject lateinit var roomAPI: RoomAPI @@ -75,27 +64,31 @@ internal class SendEventWorker(context: Context, val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) - if (params.eventId == null || params.roomId == null || params.type == null) { - // compat with old params, make it fail if any - if (params.event?.eventId != null) { - localEchoRepository.updateSendState(params.event.eventId, SendState.UNDELIVERED) + + val event = params.event + if (event?.eventId == null || event.roomId == null) { + // Old way of sending + if (params.eventId != null) { + localEchoRepository.updateSendState(params.eventId, SendState.UNDELIVERED) } return Result.success() + .also { Timber.e("Work cancelled due to bad input data") } } + if (params.lastFailureMessage != null) { - localEchoRepository.updateSendState(params.eventId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(event.eventId, SendState.UNDELIVERED) // Transmit the error return Result.success(inputData) .also { Timber.e("Work cancelled due to input error from parent") } } return try { - sendEvent(params.eventId, params.roomId, params.type, params.event?.content) + sendEvent(event.eventId, event.roomId, event.type, event.content) Result.success() } catch (exception: Throwable) { // It does start from 0, we want it to stop if it fails the third time val currentAttemptCount = runAttemptCount + 1 if (currentAttemptCount >= MAX_NUMBER_OF_RETRY_BEFORE_FAILING || !exception.shouldBeRetried()) { - localEchoRepository.updateSendState(params.eventId, SendState.UNDELIVERED) + localEchoRepository.updateSendState(event.eventId, SendState.UNDELIVERED) return Result.success() } else { Result.retry() From 28a1cf6982ffc60a919d87c2bc63fb98a7653e7a Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 27 Aug 2020 11:44:21 +0200 Subject: [PATCH 088/257] Join room: clean up after benoit's remarks --- .../api/session/permalinks/PermalinkParser.kt | 50 ++++--------------- .../features/permalink/PermalinkHandler.kt | 9 ++-- .../roomdirectory/PublicRoomsController.kt | 2 +- .../features/roomdirectory/UnknownRoomItem.kt | 3 -- 4 files changed, 14 insertions(+), 50 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt index d741367376..59e289ffd7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt @@ -18,11 +18,8 @@ package org.matrix.android.sdk.api.session.permalinks import android.net.Uri +import android.net.UrlQuerySanitizer import org.matrix.android.sdk.api.MatrixPatterns -import java.io.UnsupportedEncodingException -import java.net.URLEncoder -import java.util.ArrayList -import java.util.Collections /** * This class turns an uri to a [PermalinkData] @@ -50,7 +47,7 @@ object PermalinkParser { } val indexOfQuery = fragment.indexOf("?") val safeFragment = if (indexOfQuery != -1) fragment.substring(0, indexOfQuery) else fragment - val viaQueryParameters = fragment.getViaParameters(indexOfQuery) + val viaQueryParameters = fragment.getViaParameters() // we are limiting to 2 params val params = safeFragment @@ -84,42 +81,13 @@ object PermalinkParser { } } - private fun String.getViaParameters(indexOfQuery: Int): List { - val query = try { - substring(indexOfQuery + 1) - } catch (e: IndexOutOfBoundsException) { - return emptyList() - } - val encodedKey = try { - URLEncoder.encode("via", "UTF-8") - } catch (e: UnsupportedEncodingException) { - return emptyList() - } - val values = ArrayList() - var start = 0 - do { - val nextAmpersand = query.indexOf('&', start) - val end = if (nextAmpersand != -1) nextAmpersand else query.length - var separator = query.indexOf('=', start) - if (separator > end || separator == -1) { - separator = end - } - if (separator - start == encodedKey.length - && query.regionMatches(start, encodedKey, 0, encodedKey.length)) { - if (separator == end) { - values.add("") - } else { - values.add(Uri.decode(query.substring(separator + 1, end))) + private fun String.getViaParameters(): List { + return UrlQuerySanitizer(this) + .parameterList + .filter { + it.mParameter == "via" + }.map { + it.mValue } - } - - // Move start to end of name. - start = if (nextAmpersand != -1) { - nextAmpersand + 1 - } else { - break - } - } while (true) - return Collections.unmodifiableList(values) } } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 4ca16888a5..11c55f6a73 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -139,13 +139,15 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti return } val roomSummary = session.getRoomSummary(roomId) + val membership = roomSummary?.membership val eventId = permalinkData.eventId val roomAlias = permalinkData.getRoomAliasOrNull() return when { - roomSummary?.membership?.isActive().orFalse() -> { + membership == Membership.BAN -> context.toast(R.string.error_opening_banned_room) + membership?.isActive().orFalse() -> { navigator.openRoom(context, roomId, eventId, buildTask) } - roomSummary?.membership != Membership.BAN -> { + else -> { val roomPreviewData = RoomPreviewData( roomId = roomId, eventId = eventId, @@ -157,9 +159,6 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti ) navigator.openRoomPreview(context, roomPreviewData) } - else -> { - context.toast(R.string.error_opening_banned_room) - } } } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt index a35725815b..b71b494948 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt @@ -127,7 +127,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri return roomItem?.let { UnknownRoomItem_().apply { id(roomIdOrAlias) - matrixItem(roomItem) + matrixItem(it) avatarRenderer(this@PublicRoomsController.avatarRenderer) globalListener { callback?.onUnknownRoomClicked(roomIdOrAlias) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt index cf0ad811a2..084f518405 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/UnknownRoomItem.kt @@ -36,9 +36,6 @@ abstract class UnknownRoomItem : VectorEpoxyModel() { @EpoxyAttribute lateinit var matrixItem: MatrixItem - @EpoxyAttribute - var identifier: String? = null - @EpoxyAttribute var globalListener: (() -> Unit)? = null From d9009540ddb235084308f22fd4e59ed2d708ef77 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 27 Aug 2020 16:43:11 +0300 Subject: [PATCH 089/257] Don't try to use bluetooth headset if it is not connected. --- CHANGES.md | 1 + .../main/java/im/vector/app/features/call/CallAudioManager.kt | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c923053b24..07b50ef632 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bugfix 🐛: - Fix FontSize issue (#1483, #1787) - Fix bad color for settings icon on Android < 24 (#1786) - Change user or room avatar: when selecting Gallery, I'm not proposed to crop the selected image (#1590) + - Loudspeaker is always used (#1685) Translations 🗣: - diff --git a/vector/src/main/java/im/vector/app/features/call/CallAudioManager.kt b/vector/src/main/java/im/vector/app/features/call/CallAudioManager.kt index fde562ee63..2a773c2f9b 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallAudioManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallAudioManager.kt @@ -125,7 +125,7 @@ class CallAudioManager( } else { // if a wired headset is plugged, sound will be directed to it // (can't really force earpiece when headset is plugged) - if (isBluetoothHeadsetOn()) { + if (isBluetoothHeadsetConnected(audioManager)) { Timber.v("##VOIP: AudioManager default to WIRELESS_HEADSET ") setCurrentSoundDevice(SoundDevice.WIRELESS_HEADSET) // try now in case already connected? @@ -246,7 +246,7 @@ class CallAudioManager( } private fun isHeadsetOn(): Boolean { - return isWiredHeadsetOn() || isBluetoothHeadsetOn() + return isWiredHeadsetOn() || (audioManager?.let { isBluetoothHeadsetConnected(it) } ?: false) } private fun isWiredHeadsetOn(): Boolean { From 59fa2e28c2943e7b321ec44344de87b79c52cc40 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 15:37:10 +0200 Subject: [PATCH 090/257] Fix sonar analysis version name issue --- vector/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/build.gradle b/vector/build.gradle index ef2d6c3d9e..e55ad31ef3 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -122,6 +122,9 @@ android { // Other branches (master, features, etc.) will have version code based on application version. versionCode project.getVersionCode() + // Required for sonar analysis + versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar" + buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\"" resValue "string", "git_revision", "\"${gitRevision()}\"" From b69616117f7578cc5053b625fd32808c1819287d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 15:37:39 +0200 Subject: [PATCH 091/257] Sonar: skip project `diff-match-patch` --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index fdaef6a2f7..93ea529163 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,12 @@ project(":vector") { } } +project(":diff-match-patch") { + sonarqube { + skipProject = true + } +} + //project(":matrix-sdk-android") { // sonarqube { // properties { From cd28ad4c07aad9bf3c60d69d5ff12816c8bec254 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 15:51:28 +0200 Subject: [PATCH 092/257] Remove dead code (QrCode animation) --- .../app/features/debug/DebugMenuActivity.kt | 2 +- .../app/core/ui/views/QrCodeImageView.kt | 50 ++----------------- .../VerificationChooseMethodController.kt | 1 - .../BottomSheetVerificationQrCodeItem.kt | 5 +- 4 files changed, 5 insertions(+), 53 deletions(-) diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 855333d96b..5590e19c10 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -68,7 +68,7 @@ class DebugMenuActivity : VectorBaseActivity() { } private fun renderQrCode(text: String) { - debug_qr_code.setData(text, true) + debug_qr_code.setData(text) } @OnClick(R.id.debug_test_text_view_link) diff --git a/vector/src/main/java/im/vector/app/core/ui/views/QrCodeImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/QrCodeImageView.kt index 11e319ab78..f4b371bc52 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/QrCodeImageView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/QrCodeImageView.kt @@ -18,28 +18,23 @@ package im.vector.app.core.ui.views import android.content.Context import android.graphics.Color -import android.graphics.drawable.AnimationDrawable -import android.graphics.drawable.BitmapDrawable import android.util.AttributeSet import androidx.appcompat.widget.AppCompatImageView import im.vector.app.core.qrcode.toBitMatrix import im.vector.app.core.qrcode.toBitmap -import kotlin.random.Random class QrCodeImageView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : AppCompatImageView(context, attrs, defStyleAttr) { private var data: String? = null - private var animate = false init { setBackgroundColor(Color.WHITE) } - fun setData(data: String, animate: Boolean) { + fun setData(data: String) { this.data = data - this.animate = animate render() } @@ -53,47 +48,8 @@ class QrCodeImageView @JvmOverloads constructor( data ?.takeIf { height > 0 } ?.let { - if (animate) { - // NOT SUPPORTED YET val anim = createAnimation(it) - // NOT SUPPORTED YET setImageDrawable(anim) - // NOT SUPPORTED YET anim.start() - // NOT SUPPORTED YET setImageDrawable(BitmapDrawable(resources, it.toBitMatrix(height).toBitmap())) - val bitmap = it.toBitMatrix(height).toBitmap() - post { setImageBitmap(bitmap) } - } else { - val bitmap = it.toBitMatrix(height).toBitmap() - post { setImageBitmap(bitmap) } - } + val bitmap = it.toBitMatrix(height).toBitmap() + post { setImageBitmap(bitmap) } } } - - private fun createAnimation(data: String): AnimationDrawable { - val finalQr = data.toBitMatrix(height) - - val list = mutableListOf(finalQr) - - val random = Random(System.currentTimeMillis()) - val repeatTime = 8 - repeat(repeatTime) { index -> - val alteredQr = finalQr.clone() - for (x in 0 until alteredQr.width) { - for (y in 0 until alteredQr.height) { - if (random.nextInt(repeatTime - index) == 0) { - // Pb is that it does not toggle a whole black square, but only a pixel - alteredQr.unset(x, y) - } - } - } - list.add(alteredQr) - } - - val animDrawable = AnimationDrawable() - - list.asReversed() - .forEach { - animDrawable.addFrame(BitmapDrawable(resources, it.toBitmap()), 150) - } - - return animDrawable - } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt index 953b20cb0c..0406a63bc6 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt @@ -53,7 +53,6 @@ class VerificationChooseMethodController @Inject constructor( bottomSheetVerificationQrCodeItem { id("qr") data(state.qrCodeText) - animate(false) } dividerItem { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationQrCodeItem.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationQrCodeItem.kt index 8d78c1c9d6..41c92fa76f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationQrCodeItem.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationQrCodeItem.kt @@ -32,12 +32,9 @@ abstract class BottomSheetVerificationQrCodeItem : VectorEpoxyModel Date: Thu, 27 Aug 2020 17:38:35 +0200 Subject: [PATCH 093/257] Remove commented out code and useless code --- .../settings/VectorSettingsLabsFragment.kt | 100 +----------------- 1 file changed, 1 insertion(+), 99 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt index c8cf44778c..6a4ea83d68 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt @@ -17,7 +17,6 @@ package im.vector.app.features.settings import im.vector.app.R -import im.vector.app.core.preference.VectorSwitchPreference import javax.inject.Inject class VectorSettingsLabsFragment @Inject constructor( @@ -28,103 +27,6 @@ class VectorSettingsLabsFragment @Inject constructor( override val preferenceXmlRes = R.xml.vector_settings_labs override fun bindPref() { - // Lab - - findPreference(VectorPreferences.SETTINGS_LABS_ALLOW_EXTENDED_LOGS)?.let { - it.isChecked = vectorPreferences.labAllowedExtendedLogging() - } - - findPreference(VectorPreferences.SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB)?.let { - it.isChecked = vectorPreferences.labAddNotificationTab() - } - -// val useCryptoPref = findPreference(VectorPreferences.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY) as SwitchPreference -// val cryptoIsEnabledPref = findPreference(VectorPreferences.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY) - - if (session.cryptoService().isCryptoEnabled()) { -// mLabsCategory.removePreference(useCryptoPref) -// -// cryptoIsEnabledPref.isEnabled = false - } else { -// mLabsCategory.removePreference(cryptoIsEnabledPref) -// -// useCryptoPref.isChecked = false -// -// useCryptoPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid -> -// if (TextUtils.isEmpty(mSession.sessionParams.deviceId)) { -// activity?.let { activity -> -// AlertDialog.Builder(activity) -// .setMessage(R.string.room_settings_labs_end_to_end_warnings) -// .setPositiveButton(R.string.logout) { _, _ -> -// notImplemented() -// // TODO CommonActivityUtils.logout(activity) -// } -// .setNegativeButton(R.string.cancel) { _, _ -> -// useCryptoPref.isChecked = false -// } -// .setOnCancelListener { -// useCryptoPref.isChecked = false -// } -// .show() -// } -// } else { -// val newValue = newValueAsVoid as Boolean -// -// if (mSession.isCryptoEnabled() != newValue) { -// notImplemented() -// /* TODO -// displayLoadingView() -// -// session.enableCrypto(newValue, object : MatrixCallback { -// private fun refresh() { -// activity?.runOnUiThread { -// hideLoadingView() -// useCryptoPref.isChecked = session.isCryptoEnabled -// -// if (session.isCryptoEnabled) { -// mLabsCategory.removePreference(useCryptoPref) -// mLabsCategory.addPreference(cryptoIsEnabledPref) -// } -// } -// } -// -// override fun onSuccess(info: Void?) { -// useCryptoPref.isEnabled = false -// refresh() -// } -// -// override fun onNetworkError(e: Exception) { -// useCryptoPref.isChecked = false -// } -// -// override fun onMatrixError(e: MatrixError) { -// useCryptoPref.isChecked = false -// } -// -// override fun onUnexpectedError(e: Exception) { -// useCryptoPref.isChecked = false -// } -// }) -// */ -// } -// } -// -// true -// } - } - - // SaveMode Management -// findPreference(VectorPreferences.SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY) -// .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> -// notImplemented() -// /* TODO -// val sessions = Matrix.getMXSessions(activity) -// for (session in sessions) { -// session.setUseDataSaveMode(newValue as Boolean) -// } -// */ -// -// true -// } + // Nothing to do } } From a857d8e3063ab4e36d659869554c575d30c9dd29 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 17:39:09 +0200 Subject: [PATCH 094/257] Fix bugs detected by sonar --- build.gradle | 3 ++- .../roompreview/RoomPreviewActivity.kt | 2 ++ .../devices/VectorSettingsDevicesFragment.kt | 13 +++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 93ea529163..aa941e1445 100644 --- a/build.gradle +++ b/build.gradle @@ -100,7 +100,8 @@ project(":vector") { properties { property "sonar.sources", project(":vector").android.sourceSets.main.java.srcDirs // exclude source code from analyses separated by a colon (:) - // property "sonar.exclusions", "**/*.*" + // Exclude Java source + property "sonar.exclusions", "**/BugReporterMultipartBody.java" } } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index 8bbaa14ab0..4876bd7f98 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -28,6 +28,7 @@ import kotlinx.android.parcel.Parcelize import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.util.MatrixItem +import timber.log.Timber @Parcelize data class RoomPreviewData( @@ -83,6 +84,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { if (args?.worldReadable == true) { // TODO Room preview: Note: M does not recommend to use /events anymore, so for now we just display the room preview // TODO the same way if it was not world readable + Timber.d("just display the room preview the same way if it was not world readable") addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args) } else { addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index b33a0cb5d8..bc72f812ff 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -48,7 +48,8 @@ class VectorSettingsDevicesFragment @Inject constructor( ) : VectorBaseFragment(), DevicesController.Callback { // used to avoid requesting to enter the password for each deletion - private var mAccountPassword: String = "" + // Note: Sonar does not like to use password for member name. + private var mAccountPass: String = "" override fun getLayoutResId() = R.layout.fragment_generic_recycler @@ -91,7 +92,7 @@ class VectorSettingsDevicesFragment @Inject constructor( super.showFailure(throwable) // Password is maybe not good, for safety measure, reset it here - mAccountPassword = "" + mAccountPass = "" } override fun onDestroyView() { @@ -153,12 +154,12 @@ class VectorSettingsDevicesFragment @Inject constructor( * Show a dialog to ask for user password, or use a previously entered password. */ private fun maybeShowDeleteDeviceWithPasswordDialog() { - if (mAccountPassword.isNotEmpty()) { - viewModel.handle(DevicesAction.Password(mAccountPassword)) + if (mAccountPass.isNotEmpty()) { + viewModel.handle(DevicesAction.Password(mAccountPass)) } else { PromptPasswordDialog().show(requireActivity()) { password -> - mAccountPassword = password - viewModel.handle(DevicesAction.Password(mAccountPassword)) + mAccountPass = password + viewModel.handle(DevicesAction.Password(mAccountPass)) } } } From 02145eaa06ac153ca5f9b2e44ac0ca54e6d88c5c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 17:43:22 +0200 Subject: [PATCH 095/257] Github repository has been renamed --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- AUTHORS.md | 2 +- README.md | 2 +- build.gradle | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 77dffb43d2..34d7b40a88 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ ### Pull Request Checklist - + - [ ] Changes has been tested on an Android device or Android emulator with API 21 - [ ] UI change has been tested on both light and dark themes diff --git a/AUTHORS.md b/AUTHORS.md index 3d9dffbef5..a85beb2d6f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,4 +1,4 @@ -A full developer contributors list can be found [here](https://github.com/vector-im/riotX-android/graphs/contributors). +A full developer contributors list can be found [here](https://github.com/vector-im/element-android/graphs/contributors). # Core team: diff --git a/README.md b/README.md index 1ec425793f..ab1a121792 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,6 @@ The team will work to add them on a regular basis. ## Contributing -Please refer to [CONTRIBUTING.md](https://github.com/vector-im/riotX-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects! +Please refer to [CONTRIBUTING.md](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects! Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#element-android:matrix.org). diff --git a/build.gradle b/build.gradle index aa941e1445..84fa1cd713 100644 --- a/build.gradle +++ b/build.gradle @@ -86,10 +86,10 @@ sonarqube { property "sonar.host.url", "https://sonarcloud.io" property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName property "sonar.sourceEncoding", "UTF-8" - property "sonar.links.homepage", "https://github.com/vector-im/riotX-android/" + property "sonar.links.homepage", "https://github.com/vector-im/element-android/" property "sonar.links.ci", "https://buildkite.com/matrix-dot-org/riotx-android" - property "sonar.links.scm", "https://github.com/vector-im/riotX-android/" - property "sonar.links.issue", "https://github.com/vector-im/riotX-android/issues" + property "sonar.links.scm", "https://github.com/vector-im/element-android/" + property "sonar.links.issue", "https://github.com/vector-im/element-android/issues" property "sonar.organization", "new_vector_ltd_organization" property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid" } From 8369003bdf517cad85bf819c992277b0d473ad9d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 17:48:19 +0200 Subject: [PATCH 096/257] Sonar: rename project name and project key --- README.md | 6 +++--- build.gradle | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ab1a121792..457b18d775 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f66c690f7788bc6aa80a7628e37f3.svg?branch=develop)](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop) [![Weblate](https://translate.riot.im/widgets/element-android/-/svg-badge.svg)](https://translate.riot.im/engage/element-android/?utm_source=widget) [![Element Android Matrix room #element-android:matrix.org](https://img.shields.io/matrix/element-android:matrix.org.svg?label=%23element-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-android:matrix.org) -[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=alert_status)](https://sonarcloud.io/dashboard?id=vector.android.riotx) -[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=vector.android.riotx) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=vector.android.riotx&metric=bugs)](https://sonarcloud.io/dashboard?id=vector.android.riotx) +[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=alert_status)](https://sonarcloud.io/dashboard?id=im.vector.app.android) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=im.vector.app.android) +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=im.vector.app.android&metric=bugs)](https://sonarcloud.io/dashboard?id=im.vector.app.android) # Element Android diff --git a/build.gradle b/build.gradle index 84fa1cd713..061dd73a40 100644 --- a/build.gradle +++ b/build.gradle @@ -81,8 +81,8 @@ apply plugin: 'org.sonarqube' sonarqube { properties { - property "sonar.projectName", "RiotX-Android" - property "sonar.projectKey", "vector.android.riotx" + property "sonar.projectName", "Element-Android" + property "sonar.projectKey", "im.vector.app.android" property "sonar.host.url", "https://sonarcloud.io" property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName property "sonar.sourceEncoding", "UTF-8" From ef4f930ba2b79186591b5b5c6fa4eedcf4eef9e1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 18:19:15 +0200 Subject: [PATCH 097/257] Don't pause the sync thread if there is an active or pending call. But pause the sync thread when there is no active call and the app is the background. Authors: Onuray, I just rebased and squashed all the commit --- CHANGES.md | 1 + .../api/session/call/CallSignalingService.kt | 2 + .../session/call/ActiveCallHandler.kt | 45 +++++++++++++++++++ .../call/DefaultCallSignalingService.kt | 25 ++++++----- .../internal/session/sync/job/SyncThread.kt | 34 ++++++++++++-- 5 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/ActiveCallHandler.kt diff --git a/CHANGES.md b/CHANGES.md index bc363683a2..1ffb6bcad0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Bugfix 🐛: - Fix bad color for settings icon on Android < 24 (#1786) - Change user or room avatar: when selecting Gallery, I'm not proposed to crop the selected image (#1590) - Fix uploads still don't work with room v6 (#1879) + - Can't handle ongoing call events in background (#1992) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt index 2962f9fac3..382ab54248 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/call/CallSignalingService.kt @@ -34,4 +34,6 @@ interface CallSignalingService { fun removeCallListener(listener: CallsListener) fun getCallWithId(callId: String) : MxCall? + + fun isThereAnyActiveCall(): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/ActiveCallHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/ActiveCallHandler.kt new file mode 100644 index 0000000000..40f5a56c33 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/ActiveCallHandler.kt @@ -0,0 +1,45 @@ +/* + * 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 org.matrix.android.sdk.internal.session.call + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import org.matrix.android.sdk.api.session.call.MxCall +import org.matrix.android.sdk.internal.session.SessionScope +import javax.inject.Inject + +@SessionScope +internal class ActiveCallHandler @Inject constructor() { + + private val activeCallListLiveData: MutableLiveData> by lazy { + MutableLiveData>(mutableListOf()) + } + + fun addCall(call: MxCall) { + activeCallListLiveData.postValue(activeCallListLiveData.value?.apply { add(call) }) + } + + fun removeCall(callId: String) { + activeCallListLiveData.postValue(activeCallListLiveData.value?.apply { removeAll { it.callId == callId } }) + } + + fun getCallWithId(callId: String): MxCall? { + return activeCallListLiveData.value?.find { it.callId == callId } + } + + fun getActiveCallsLiveData(): LiveData> = activeCallListLiveData +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt index 0b097cf64f..d9bc66eddf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/call/DefaultCallSignalingService.kt @@ -49,6 +49,7 @@ import javax.inject.Inject internal class DefaultCallSignalingService @Inject constructor( @UserId private val userId: String, + private val activeCallHandler: ActiveCallHandler, private val localEchoEventFactory: LocalEchoEventFactory, private val roomEventSender: RoomEventSender, private val taskExecutor: TaskExecutor, @@ -57,8 +58,6 @@ internal class DefaultCallSignalingService @Inject constructor( private val callListeners = mutableSetOf() - private val activeCalls = mutableListOf() - private val cachedTurnServerResponse = object { // Keep one minute safe to avoid considering the data is valid and then actually it is not when effectively using it. private val MIN_TTL = 60 @@ -97,7 +96,7 @@ internal class DefaultCallSignalingService @Inject constructor( } override fun createOutgoingCall(roomId: String, otherUserId: String, isVideoCall: Boolean): MxCall { - return MxCallImpl( + val call = MxCallImpl( callId = UUID.randomUUID().toString(), isOutgoing = true, roomId = roomId, @@ -106,8 +105,9 @@ internal class DefaultCallSignalingService @Inject constructor( isVideoCall = isVideoCall, localEchoEventFactory = localEchoEventFactory, roomEventSender = roomEventSender - ).also { - activeCalls.add(it) + ) + activeCallHandler.addCall(call).also { + return call } } @@ -120,8 +120,12 @@ internal class DefaultCallSignalingService @Inject constructor( } override fun getCallWithId(callId: String): MxCall? { - Timber.v("## VOIP getCallWithId $callId all calls ${activeCalls.map { it.callId }}") - return activeCalls.find { it.callId == callId } + Timber.v("## VOIP getCallWithId $callId all calls ${activeCallHandler.getActiveCallsLiveData().value?.map { it.callId }}") + return activeCallHandler.getCallWithId(callId) + } + + override fun isThereAnyActiveCall(): Boolean { + return activeCallHandler.getActiveCallsLiveData().value?.isNotEmpty() == true } internal fun onCallEvent(event: Event) { @@ -152,6 +156,7 @@ internal class DefaultCallSignalingService @Inject constructor( // Always ignore local echos of invite return } + event.getClearContent().toModel()?.let { content -> val incomingCall = MxCallImpl( callId = content.callId ?: return@let, @@ -163,7 +168,7 @@ internal class DefaultCallSignalingService @Inject constructor( localEchoEventFactory = localEchoEventFactory, roomEventSender = roomEventSender ) - activeCalls.add(incomingCall) + activeCallHandler.addCall(incomingCall) onCallInvite(incomingCall, content) } } @@ -185,8 +190,8 @@ internal class DefaultCallSignalingService @Inject constructor( return } + activeCallHandler.removeCall(content.callId) onCallHangup(content) - activeCalls.removeAll { it.callId == content.callId } } } EventType.CALL_CANDIDATES -> { @@ -195,7 +200,7 @@ internal class DefaultCallSignalingService @Inject constructor( return } event.getClearContent().toModel()?.let { content -> - activeCalls.firstOrNull { it.callId == content.callId }?.let { + activeCallHandler.getCallWithId(content.callId)?.let { onCallIceCandidate(it, content) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt index 1a2d6b1fd3..9fd9c313db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.job import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer import com.squareup.moshi.JsonEncodingException import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.isTokenError @@ -30,11 +31,14 @@ import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.util.Debouncer import org.matrix.android.sdk.internal.util.createUIHandler import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.session.call.MxCall +import org.matrix.android.sdk.internal.session.call.ActiveCallHandler import timber.log.Timber import java.net.SocketTimeoutException import java.util.Timer @@ -48,8 +52,9 @@ private const val DEFAULT_LONG_POOL_TIMEOUT = 30_000L internal class SyncThread @Inject constructor(private val syncTask: SyncTask, private val typingUsersTracker: DefaultTypingUsersTracker, private val networkConnectivityChecker: NetworkConnectivityChecker, - private val backgroundDetectionObserver: BackgroundDetectionObserver) - : Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener { + private val backgroundDetectionObserver: BackgroundDetectionObserver, + private val activeCallHandler: ActiveCallHandler +) : Thread(), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener { private var state: SyncState = SyncState.Idle private var liveState = MutableLiveData(state) @@ -62,6 +67,12 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, private var isTokenValid = true private var retryNoNetworkTask: TimerTask? = null + private val activeCallListObserver = Observer> { activeCalls -> + if (activeCalls.isEmpty() && backgroundDetectionObserver.isInBackground) { + pause() + } + } + init { updateStateTo(SyncState.Idle) } @@ -115,9 +126,11 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, override fun run() { Timber.v("Start syncing...") + isStarted = true networkConnectivityChecker.register(this) backgroundDetectionObserver.register(this) + registerActiveCallsObserver() while (state != SyncState.Killing) { Timber.v("Entering loop, state: $state") if (!isStarted) { @@ -163,6 +176,19 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, updateStateTo(SyncState.Killed) backgroundDetectionObserver.unregister(this) networkConnectivityChecker.unregister(this) + unregisterActiveCallsObserver() + } + + private fun registerActiveCallsObserver() { + syncScope.launch(Dispatchers.Main) { + activeCallHandler.getActiveCallsLiveData().observeForever(activeCallListObserver) + } + } + + private fun unregisterActiveCallsObserver() { + syncScope.launch(Dispatchers.Main) { + activeCallHandler.getActiveCallsLiveData().removeObserver(activeCallListObserver) + } } private suspend fun doSync(params: SyncTask.Params) { @@ -215,6 +241,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, } override fun onMoveToBackground() { - pause() + if (activeCallHandler.getActiveCallsLiveData().value.isNullOrEmpty()) { + pause() + } } } From 9dbe9c728682564f8ce81bc3e1b70ec85e4fa369 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Aug 2020 22:44:55 +0200 Subject: [PATCH 098/257] Typo in comment --- vector/src/main/res/layout/item_device.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/item_device.xml b/vector/src/main/res/layout/item_device.xml index 9917cc0e94..6d63b1c3a7 100644 --- a/vector/src/main/res/layout/item_device.xml +++ b/vector/src/main/res/layout/item_device.xml @@ -27,7 +27,7 @@ tools:text="Riot X" /> Date: Thu, 27 Aug 2020 22:46:30 +0200 Subject: [PATCH 099/257] Fix a crash that would occur if it was not dead code --- .../org/matrix/android/sdk/internal/session/room/RoomAPI.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index d8df86be8f..7eab3041af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -220,9 +220,9 @@ internal interface RoomAPI { */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}") fun sendRelation(@Path("roomId") roomId: String, - @Path("parentId") parent_id: String, + @Path("parent_id") parent_id: String, @Path("relation_type") relationType: String, - @Path("eventType") eventType: String, + @Path("event_type") eventType: String, @Body content: Content? ): Call From 812563f68baa25ead766973de012f726bb24c44e Mon Sep 17 00:00:00 2001 From: Tirifto Date: Thu, 27 Aug 2020 15:04:31 +0000 Subject: [PATCH 100/257] Translated using Weblate (Esperanto) Currently translated at 25.5% (471 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/eo/ --- vector/src/main/res/values-eo/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index 91ddaae665..1fa3f361af 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -603,4 +603,10 @@ Vi ne havas permeson ekigi grupan vokon en ĉi tiu ĉambro + Grupa voko jam daŭras! + Komenci grupan vidvokon + Komenci grupan voĉvokon + Grupaj vokoj uzas la politikon de Jitsi pri permesoj kaj sekureco. Ĉiuj personoj en la ĉambro vidos aliĝilon dum la voko daŭros. + Vi ne povas voki sola + Vi ne povas voki sola; atendu aliajn partoprenantojn From 9fbf97f4cb062ffe2b7033f62bc8aea80f5c1b38 Mon Sep 17 00:00:00 2001 From: random Date: Thu, 27 Aug 2020 16:39:48 +0000 Subject: [PATCH 101/257] Translated using Weblate (Italian) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/it/ --- vector/src/main/res/values-it/strings.xml | 38 ++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index bade2d66b7..4a32a351f7 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -630,7 +630,7 @@ Informazioni sessione del mittente Nome pubblico Nome pubblico - ID + ID sessione Chiave sessione Verifica Impronta digitale Ed25519 @@ -1728,7 +1728,7 @@ Segnala questo contenuto Motivo della segnalazione SEGNALA - BLOCCA UTENTE + IGNORA UTENTE Contenuto segnalato Questo contenuto è stato segnalato. @@ -1785,7 +1785,7 @@ Leggi media protetti da DRM Questo non è un indirizzo di server Matrix valido - Blocca utente + Ignora utente Tutti i messaggi (rumoroso) Tutti i messaggi @@ -2620,4 +2620,34 @@ Conferma il PIN per disattivarlo Impedisci chiamate accidentali Chiedi conferma prima di iniziare una chiamata - +Non hai il permesso di avviare una chiamata di gruppo in questa stanza + Una chiamata di gruppo è già in corso! + Avvia conferenza video + Avvia conferenza audio + Le conferenze usano la sicurezza di Jitsi e le sua politica sui permessi. Tutte le persone attualmente nella stanza vedranno un invito per unirsi quando la conferenza è in corso. + Non puoi chiamare te stesso + Non puoi chiamare te stesso, attendi che i partecipanti accettino l\'invito + Aggiunta del widget fallita + Rimozione del widget fallita + + %1$d/%2$d chiave importata correttamente. + %1$d/%2$d chiavi importate correttamente. + + + Gestisci integrazioni + Nessun widget attivo + La stanza è stata creata, ma alcuni inviti non sono stati spediti per il seguente motivo: +\n +\n%s + + + %1$s, %2$s e %3$d altro hanno letto + %1$s, %2$s e altri %3$d hanno letto + + + Codice sbagliato, %d tentativo rimasto + Codice sbagliato, %d tentativi rimasti + + Attenzione! Ultimo tentativo rimasto prima di venire disconnesso! + Troppi errori, sei stato disconnesso + From a107bdd8497e3e27d356d5f5931ccb2e876d51e6 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Thu, 27 Aug 2020 00:29:21 +0000 Subject: [PATCH 102/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1849 of 1849 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.riot.im/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 08bd5f906e..06f7ad2484 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -615,7 +615,7 @@ Informação sobre a sessão do remetente Nome público do aparelho Nome - ID da Sessão + ID da sessão Chave da sessão Confirmação Impressão digital ed25519 @@ -1865,7 +1865,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Denunciar conteúdo Motivo para denúnciar este conteúdo RELATÓRIO - IGNORAR USUÁRIO + BLOQUEAR USUÁRIO Conteúdo relatado Este conteúdo foi relatado. @@ -1886,7 +1886,7 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Não há conexão de rede no momento - Ignorar usuário + Bloquear usuário Todas as mensagens novas (com som) Todas as mensagens novas @@ -2612,34 +2612,34 @@ Na próxima tela, você será solicitado a permitir que o Element funcione sempr Confirme o PIN para desativar o PIN Evitar chamadas acidentais Confirmarei a intenção de iniciar uma chamada -Você não tem permissão para iniciar uma teleconferência nesta sala - Uma conferência já está em andamento! - Iniciar reunião em vídeo - Iniciar reunião de áudio - As reuniões utilizam as políticas de segurança e permissão de Jitsi. Todas as pessoas que estão atualmente na sala verão um convite para participar enquanto sua reunião está acontecendo. +Você não tem permissão para iniciar uma chamada em grupo nesta sala + Uma chamada em grupo já está em andamento! + Iniciar chamada de vídeo + Iniciar chamada de voz + As chamadas utilizam as políticas de segurança e permissão do Jitsi. Todas as pessoas que estão atualmente na sala verão um convite para participar enquanto sua chamada estiver acontecendo. Você não pode iniciar uma chamada com você mesmo - Você não pode iniciar uma chamada consigo mesmo, esperar que os participantes aceitem o convite - Falha ao adicionar widget - Falha ao remover widget + Você não pode iniciar uma chamada consigo mesmo. Aguarde os participantes aceitarem o convite + Falha ao adicionar o widget + Falha ao remover o widget %1$d/%2$d chave importada com êxito. %1$d/%2$d chaves importadas com êxito. Gerenciar integrações - Sem widgets ativos + Nenhum widget ativo A sala foi criada, mas alguns convites não foram enviados pelo seguinte motivo: \n \n%s - %1$s, %2$s e %3$d um outro leu + %1$s, %2$s e %3$d outro leu %1$s, %2$s e %3$d outros leram Código errado, %d tentativa restante Código errado, %d tentativas restantes - Advertência! Última tentativa restante antes de logout! - Demasiados erros, você foi desconectado + Atenção! Última tentativa restante antes de você ser desconectada/o! + Muitos erros, você foi desconectada/o From 22771a84f1613fc81a7d77cfc39109909d4c8c16 Mon Sep 17 00:00:00 2001 From: Marcelo Filho Date: Wed, 26 Aug 2020 22:00:29 +0000 Subject: [PATCH 103/257] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (235 of 235 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.riot.im/projects/element-android/element-sdk/pt_BR/ --- matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml b/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml index 6346bf2cf4..97c20c0d49 100644 --- a/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml +++ b/matrix-sdk-android/src/main/res/values-pt-rBR/strings.xml @@ -25,9 +25,9 @@ %s aceitou a chamada. %s encerrou a chamada. %1$s deixou o histórico futuro da sala visível para %2$s - todos os membros da sala, a partir do momento em que foram convidados. - todos os membros da sala, a partir do momento em que entraram nela. - todos os membros da sala. + todos os participantes da sala, a partir do momento em que foram convidados. + todos os participantes da sala, a partir do momento em que entraram nela. + todos os participantes da sala. qualquer pessoa. desconhecido (%s). %1$s ativou a criptografia de ponta a ponta (%2$s) From ee9c73fde165c1690878df6b06af9903fcc74ee8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 08:58:52 +0200 Subject: [PATCH 104/257] Sonar: rename variables and parameter to follow naming convention --- .../crypto/AttachmentEncryptionTest.kt | 24 ++++++++--------- .../AddThreePidRegistrationParams.kt | 2 +- .../auth/registration/RegistrationParams.kt | 3 ++- .../crypto/MXMegolmExportEncryption.kt | 26 +++++++++---------- .../crypto/algorithms/olm/MXOlmDecryption.kt | 8 +++--- .../attachments/MXEncryptedAttachments.kt | 2 +- .../crypto/model/event/OlmPayloadContent.kt | 16 ++++++++---- .../internal/crypto/model/rest/DeviceInfo.kt | 2 +- .../crypto/model/rest/EncryptedFileKey.kt | 4 +-- .../crypto/store/db/SafeObjectInputStream.kt | 2 +- .../SASDefaultVerificationTransaction.kt | 4 +-- .../sdk/internal/session/room/RoomAPI.kt | 10 +++---- .../room/create/CreateRoomBodyBuilder.kt | 4 +-- .../membership/threepid/InviteThreePidTask.kt | 6 ++--- .../membership/threepid/ThreePidInviteBody.kt | 12 ++++++--- .../room/relation/SendRelationWorker.kt | 4 +-- .../internal/session/sync/model/DeviceInfo.kt | 17 +++++++----- .../android/sdk/internal/util/CompatUtil.kt | 21 +++++++-------- .../vector/app/core/utils/PermissionsTools.kt | 18 ++++++------- .../VerificationChooseMethodController.kt | 2 +- .../VerificationChooseMethodViewModel.kt | 6 ++--- .../app/features/html/FontTagHandler.kt | 6 ++--- .../features/reactions/widget/CircleView.kt | 16 ++++++------ .../app/features/reactions/widget/DotsView.kt | 8 +++--- .../VectorSettingsSecurityPrivacyFragment.kt | 2 +- .../devices/VectorSettingsDevicesFragment.kt | 4 +-- 26 files changed, 122 insertions(+), 107 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt index cb24cbb242..80e7b6dbbb 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt @@ -19,9 +19,6 @@ package org.matrix.android.sdk.internal.crypto import android.os.MemoryFile import android.util.Base64 import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull @@ -29,6 +26,9 @@ import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters +import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments +import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey import java.io.InputStream /** @@ -40,15 +40,15 @@ import java.io.InputStream class AttachmentEncryptionTest { private fun checkDecryption(input: String, encryptedFileInfo: EncryptedFileInfo): String { - val `in` = Base64.decode(input, Base64.DEFAULT) + val inputAsByteArray = Base64.decode(input, Base64.DEFAULT) val inputStream: InputStream - inputStream = if (`in`.isEmpty()) { - `in`.inputStream() + inputStream = if (inputAsByteArray.isEmpty()) { + inputAsByteArray.inputStream() } else { - val memoryFile = MemoryFile("file" + System.currentTimeMillis(), `in`.size) - memoryFile.outputStream.write(`in`) + val memoryFile = MemoryFile("file" + System.currentTimeMillis(), inputAsByteArray.size) + memoryFile.outputStream.write(inputAsByteArray) memoryFile.inputStream } @@ -73,7 +73,7 @@ class AttachmentEncryptionTest { key = EncryptedFileKey( alg = "A256CTR", k = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - key_ops = listOf("encrypt", "decrypt"), + keyOps = listOf("encrypt", "decrypt"), kty = "oct", ext = true ), @@ -92,7 +92,7 @@ class AttachmentEncryptionTest { key = EncryptedFileKey( alg = "A256CTR", k = "__________________________________________8", - key_ops = listOf("encrypt", "decrypt"), + keyOps = listOf("encrypt", "decrypt"), kty = "oct", ext = true ), @@ -111,7 +111,7 @@ class AttachmentEncryptionTest { key = EncryptedFileKey( alg = "A256CTR", k = "__________________________________________8", - key_ops = listOf("encrypt", "decrypt"), + keyOps = listOf("encrypt", "decrypt"), kty = "oct", ext = true ), @@ -132,7 +132,7 @@ class AttachmentEncryptionTest { key = EncryptedFileKey( alg = "A256CTR", k = "__________________________________________8", - key_ops = listOf("encrypt", "decrypt"), + keyOps = listOf("encrypt", "decrypt"), kty = "oct", ext = true ), diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AddThreePidRegistrationParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AddThreePidRegistrationParams.kt index 7fbdaacb81..3e6e3054b5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AddThreePidRegistrationParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AddThreePidRegistrationParams.kt @@ -54,7 +54,7 @@ internal data class AddThreePidRegistrationParams( * This parameter is ignored when the homeserver handles 3PID verification. */ @Json(name = "id_server") - val id_server: String? = null, + val idServer: String? = null, /* ========================================================================================== * For emails diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/RegistrationParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/RegistrationParams.kt index 4089e280d7..ca475566f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/RegistrationParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/RegistrationParams.kt @@ -44,5 +44,6 @@ internal data class RegistrationParams( // Temporary flag to notify the server that we support msisdn flow. Used to prevent old app // versions to end up in fallback because the HS returns the msisdn flow which they don't support - val x_show_msisdn: Boolean? = null + @Json(name = "x_show_msisdn") + val xShowMsisdn: Boolean? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt index 4526ba8a51..85ecc540cd 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt @@ -145,7 +145,7 @@ object MXMegolmExportEncryption { */ @Throws(Exception::class) @JvmOverloads - fun encryptMegolmKeyFile(data: String, password: String, kdf_rounds: Int = DEFAULT_ITERATION_COUNT): ByteArray { + fun encryptMegolmKeyFile(data: String, password: String, kdfRounds: Int = DEFAULT_ITERATION_COUNT): ByteArray { if (password.isEmpty()) { throw Exception("Empty password is not supported") } @@ -163,7 +163,7 @@ object MXMegolmExportEncryption { // of a single bit of salt is a price we have to pay. iv[9] = iv[9] and 0x7f - val deriveKey = deriveKeys(salt, kdf_rounds, password) + val deriveKey = deriveKeys(salt, kdfRounds, password) val decryptCipher = Cipher.getInstance("AES/CTR/NoPadding") @@ -188,10 +188,10 @@ object MXMegolmExportEncryption { System.arraycopy(iv, 0, resultBuffer, idx, iv.size) idx += iv.size - resultBuffer[idx++] = (kdf_rounds shr 24 and 0xff).toByte() - resultBuffer[idx++] = (kdf_rounds shr 16 and 0xff).toByte() - resultBuffer[idx++] = (kdf_rounds shr 8 and 0xff).toByte() - resultBuffer[idx++] = (kdf_rounds and 0xff).toByte() + resultBuffer[idx++] = (kdfRounds shr 24 and 0xff).toByte() + resultBuffer[idx++] = (kdfRounds shr 16 and 0xff).toByte() + resultBuffer[idx++] = (kdfRounds shr 8 and 0xff).toByte() + resultBuffer[idx++] = (kdfRounds and 0xff).toByte() System.arraycopy(cipherArray, 0, resultBuffer, idx, cipherArray.size) idx += cipherArray.size @@ -320,26 +320,26 @@ object MXMegolmExportEncryption { // 512 bits key length val key = ByteArray(64) - val Uc = ByteArray(64) + val uc = ByteArray(64) // U1 = PRF(Password, Salt || INT_32_BE(i)) prf.update(salt) val int32BE = ByteArray(4) { 0.toByte() } int32BE[3] = 1.toByte() prf.update(int32BE) - prf.doFinal(Uc, 0) + prf.doFinal(uc, 0) // copy to the key - System.arraycopy(Uc, 0, key, 0, Uc.size) + System.arraycopy(uc, 0, key, 0, uc.size) for (index in 2..iterations) { // Uc = PRF(Password, Uc-1) - prf.update(Uc) - prf.doFinal(Uc, 0) + prf.update(uc) + prf.doFinal(uc, 0) // F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc - for (byteIndex in Uc.indices) { - key[byteIndex] = key[byteIndex] xor Uc[byteIndex] + for (byteIndex in uc.indices) { + key[byteIndex] = key[byteIndex] xor uc[byteIndex] } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt index d4295e2cec..a4e3ee950d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -102,7 +102,7 @@ internal class MXOlmDecryption( String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)) } - val recipientKeys = olmPayloadContent.recipient_keys ?: run { + val recipientKeys = olmPayloadContent.recipientKeys ?: run { Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" + " property; cannot prevent unknown-key attack") throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY, @@ -129,10 +129,10 @@ internal class MXOlmDecryption( String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)) } - if (olmPayloadContent.room_id != event.roomId) { - Timber.e("## decryptEvent() : Event ${event.eventId}: original room ${olmPayloadContent.room_id} does not match reported room ${event.roomId}") + if (olmPayloadContent.roomId != event.roomId) { + Timber.e("## decryptEvent() : Event ${event.eventId}: original room ${olmPayloadContent.roomId} does not match reported room ${event.roomId}") throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ROOM, - String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.room_id)) + String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.roomId)) } val keys = olmPayloadContent.keys ?: run { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt index a6d95cc87a..9e1ef19b3a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -93,7 +93,7 @@ internal object MXEncryptedAttachments { key = EncryptedFileKey( alg = "A256CTR", ext = true, - key_ops = listOf("encrypt", "decrypt"), + keyOps = listOf("encrypt", "decrypt"), kty = "oct", k = base64ToBase64Url(Base64.encodeToString(key, Base64.DEFAULT)) ), diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt index a3a9ee2e51..bf18cad0f4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt @@ -16,6 +16,7 @@ */ package org.matrix.android.sdk.internal.crypto.model.event +import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.internal.di.MoshiProvider @@ -27,27 +28,32 @@ data class OlmPayloadContent( /** * The room id */ - var room_id: String? = null, + @Json(name = "room_id") + val roomId: String? = null, /** * The sender */ - var sender: String? = null, + @Json(name = "sender") + val sender: String? = null, /** * The recipient */ - var recipient: String? = null, + @Json(name = "recipient") + val recipient: String? = null, /** * the recipient keys */ - var recipient_keys: Map? = null, + @Json(name = "recipient_keys") + val recipientKeys: Map? = null, /** * The keys */ - var keys: Map? = null + @Json(name = "keys") + val keys: Map? = null ) { fun toJsonString(): String { return MoshiProvider.providesMoshi().adapter(OlmPayloadContent::class.java).toJson(this) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt index 97c7c59b50..0c6d03613a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt @@ -31,7 +31,7 @@ data class DeviceInfo( * The owner user id (not documented and useless but the homeserver sent it. You should not need it) */ @Json(name = "user_id") - val user_id: String? = null, + val userId: String? = null, /** * The device id diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt index f0a680cfd3..077fd4451f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt @@ -37,7 +37,7 @@ data class EncryptedFileKey( * Required. Key operations. Must at least contain "encrypt" and "decrypt". */ @Json(name = "key_ops") - val key_ops: List? = null, + val keyOps: List? = null, /** * Required. Key type. Must be "oct". @@ -63,7 +63,7 @@ data class EncryptedFileKey( return false } - if (key_ops?.contains("encrypt") != true || !key_ops.contains("decrypt")) { + if (keyOps?.contains("encrypt") != true || !keyOps.contains("decrypt")) { return false } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt index 17538c7cbe..3f811ed7d2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/SafeObjectInputStream.kt @@ -28,7 +28,7 @@ import java.io.ObjectStreamClass * * Ref: https://stackoverflow.com/questions/3884492/how-can-i-change-package-for-a-bunch-of-java-serializable-classes */ -internal class SafeObjectInputStream(`in`: InputStream) : ObjectInputStream(`in`) { +internal class SafeObjectInputStream(inputStream: InputStream) : ObjectInputStream(inputStream) { init { enableResolveObject(true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt index 7ebd3b51b0..17eb33c886 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt @@ -175,8 +175,8 @@ internal abstract class SASDefaultVerificationTransaction( ?.unpaddedBase64PublicKey ?.let { masterPublicKey -> val crossSigningKeyId = "ed25519:$masterPublicKey" - macUsingAgreedMethod(masterPublicKey, baseInfo + crossSigningKeyId)?.let { MSKMacString -> - keyMap[crossSigningKeyId] = MSKMacString + macUsingAgreedMethod(masterPublicKey, baseInfo + crossSigningKeyId)?.let { mskMacString -> + keyMap[crossSigningKeyId] = mskMacString } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 7eab3041af..35c20cf5cb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -220,7 +220,7 @@ internal interface RoomAPI { */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}") fun sendRelation(@Path("roomId") roomId: String, - @Path("parent_id") parent_id: String, + @Path("parent_id") parentId: String, @Path("relation_type") relationType: String, @Path("event_type") eventType: String, @Body content: Content? @@ -296,16 +296,16 @@ internal interface RoomAPI { * This cannot be undone. * Users may redact their own events, and any user with a power level greater than or equal to the redact power level of the room may redact events there. * - * @param txId the transaction Id - * @param roomId the room id - * @param eventId the event to delete + * @param txId the transaction Id + * @param roomId the room id + * @param eventId the event to delete * @param reason json containing reason key {"reason": "Indecent material"} */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/redact/{eventId}/{txnId}") fun redactEvent( @Path("txnId") txId: String, @Path("roomId") roomId: String, - @Path("eventId") parent_id: String, + @Path("eventId") eventId: String, @Body reason: Map ): Call diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 6e450e5428..0a814a4c93 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -57,8 +57,8 @@ internal class CreateRoomBodyBuilder @Inject constructor( invites.map { ThreePidInviteBody( - id_server = identityServerUrlWithoutProtocol, - id_access_token = identityServerAccessToken, + idServer = identityServerUrlWithoutProtocol, + idAccessToken = identityServerAccessToken, medium = it.toMedium(), address = it.value ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt index b18e44360d..88809fec13 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/InviteThreePidTask.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.membership.threepid +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.toMedium @@ -28,7 +29,6 @@ import org.matrix.android.sdk.internal.session.identity.data.IdentityStore import org.matrix.android.sdk.internal.session.identity.data.getIdentityServerUrlWithoutProtocol import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import org.greenrobot.eventbus.EventBus import javax.inject.Inject internal interface InviteThreePidTask : Task { @@ -55,8 +55,8 @@ internal class DefaultInviteThreePidTask @Inject constructor( return executeRequest(eventBus) { val body = ThreePidInviteBody( - id_server = identityServerUrlWithoutProtocol, - id_access_token = identityServerAccessToken, + idServer = identityServerUrlWithoutProtocol, + idAccessToken = identityServerAccessToken, medium = params.threePid.toMedium(), address = params.threePid.value ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/ThreePidInviteBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/ThreePidInviteBody.kt index 93b5c577fc..5b0098dc9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/ThreePidInviteBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/threepid/ThreePidInviteBody.kt @@ -25,18 +25,22 @@ internal data class ThreePidInviteBody( /** * Required. The hostname+port of the identity server which should be used for third party identifier lookups. */ - @Json(name = "id_server") val id_server: String, + @Json(name = "id_server") + val idServer: String, /** * Required. An access token previously registered with the identity server. Servers can treat this as optional * to distinguish between r0.5-compatible clients and this specification version. */ - @Json(name = "id_access_token") val id_access_token: String, + @Json(name = "id_access_token") + val idAccessToken: String, /** * Required. The kind of address being passed in the address field, for example email. */ - @Json(name = "medium") val medium: String, + @Json(name = "medium") + val medium: String, /** * Required. The invitee's third party identifier. */ - @Json(name = "address") val address: String + @Json(name = "address") + val address: String ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt index dc72c3b96b..fc7f712629 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/SendRelationWorker.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass +import org.greenrobot.eventbus.EventBus import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel @@ -31,7 +32,6 @@ import org.matrix.android.sdk.internal.session.room.send.SendResponse import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import org.matrix.android.sdk.internal.worker.getSessionComponent -import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject @@ -92,7 +92,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) : executeRequest(eventBus) { apiCall = roomAPI.sendRelation( roomId = roomId, - parent_id = relatedEventId, + parentId = relatedEventId, relationType = relationType, eventType = localEvent.type, content = localEvent.content diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceInfo.kt index 226486596e..0e7fbf492f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/DeviceInfo.kt @@ -16,6 +16,7 @@ */ package org.matrix.android.sdk.internal.session.sync.model +import com.squareup.moshi.Json import com.squareup.moshi.JsonClass /** @@ -26,26 +27,30 @@ internal data class DeviceInfo( /** * The owner user id */ - val user_id: String? = null, + @Json(name = "user_id") + val userId: String? = null, /** * The device id */ - val device_id: String? = null, + @Json(name = "device_id") + val deviceId: String? = null, /** * The device display name */ - val display_name: String? = null, + @Json(name = "display_name") + val displayName: String? = null, /** * The last time this device has been seen. */ - val last_seen_ts: Long = 0, + @Json(name = "last_seen_ts") + val lastSeenTs: Long = 0, /** * The last ip address */ - val last_seen_ip: String? = null - + @Json(name = "last_seen_ip") + val lastSeenIp: String? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt index 6583dc89ea..6a5cfec095 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt @@ -257,12 +257,11 @@ object CompatUtil { /** * Create a CipherInputStream instance. - * Before Kitkat, this method will return `in` because local storage encryption is not implemented for devices before KitKat. - * Warning, if `in` is not an encrypted stream, it's up to the caller to close and reopen `in`, because the stream has been read. + * Warning, if inputStream is not an encrypted stream, it's up to the caller to close and reopen inputStream, because the stream has been read. * - * @param in the input stream - * @param context the context holding the application shared preferences - * @return in, or the created InputStream, or null if the InputStream `in` does not contain encrypted data + * @param inputStream the input stream + * @param context the context holding the application shared preferences + * @return inputStream, or the created InputStream, or null if the InputStream inputStream does not contain encrypted data */ @Throws(NoSuchPaddingException::class, NoSuchAlgorithmException::class, @@ -274,15 +273,15 @@ object CompatUtil { NoSuchProviderException::class, InvalidAlgorithmParameterException::class, IOException::class) - fun createCipherInputStream(`in`: InputStream, context: Context): InputStream? { - val iv_len = `in`.read() - if (iv_len != AES_GCM_IV_LENGTH) { - Timber.e(TAG, "Invalid IV length $iv_len") + fun createCipherInputStream(inputStream: InputStream, context: Context): InputStream? { + val ivLen = inputStream.read() + if (ivLen != AES_GCM_IV_LENGTH) { + Timber.e(TAG, "Invalid IV length $ivLen") return null } val iv = ByteArray(AES_GCM_IV_LENGTH) - `in`.read(iv) + inputStream.read(iv) val cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE) @@ -296,6 +295,6 @@ object CompatUtil { cipher.init(Cipher.DECRYPT_MODE, keyAndVersion.secretKey, spec) - return CipherInputStream(`in`, cipher) + return CipherInputStream(inputStream, cipher) } } diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index 38c97830ca..7bb060f075 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -272,29 +272,29 @@ private fun checkPermissions(permissionsToBeGrantedBitMap: Int, /** * Helper method used in [.checkPermissions] to populate the list of the - * permissions to be granted (permissionsListToBeGranted_out) and the list of the permissions already denied (permissionAlreadyDeniedList_out). + * permissions to be granted (permissionsListToBeGrantedOut) and the list of the permissions already denied (permissionAlreadyDeniedListOut). * - * @param activity calling activity - * @param permissionAlreadyDeniedList_out list to be updated with the permissions already denied by the user - * @param permissionsListToBeGranted_out list to be updated with the permissions to be granted - * @param permissionType the permission to be checked + * @param activity calling activity + * @param permissionAlreadyDeniedListOut list to be updated with the permissions already denied by the user + * @param permissionsListToBeGrantedOut list to be updated with the permissions to be granted + * @param permissionType the permission to be checked * @return true if the permission requires to be granted, false otherwise */ private fun updatePermissionsToBeGranted(activity: Activity, - permissionAlreadyDeniedList_out: MutableList, - permissionsListToBeGranted_out: MutableList, + permissionAlreadyDeniedListOut: MutableList, + permissionsListToBeGrantedOut: MutableList, permissionType: String): Boolean { var isRequestPermissionRequested = false // add permission to be granted - permissionsListToBeGranted_out.add(permissionType) + permissionsListToBeGrantedOut.add(permissionType) if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity.applicationContext, permissionType)) { isRequestPermissionRequested = true // add permission to the ones that were already asked to the user if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permissionType)) { - permissionAlreadyDeniedList_out.add(permissionType) + permissionAlreadyDeniedListOut.add(permissionType) } } return isRequestPermissionRequested diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt index 0406a63bc6..ed3bdc5825 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt @@ -84,7 +84,7 @@ class VerificationChooseMethodController @Inject constructor( iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)) listener { listener?.doVerifyBySas() } } - } else if (state.SASModeAvailable) { + } else if (state.sasModeAvailable) { bottomSheetVerificationActionItem { id("openEmoji") title(stringProvider.getString(R.string.verification_no_scan_emoji_title)) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index c2e367d8d5..e309869479 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -39,7 +39,7 @@ data class VerificationChooseMethodViewState( val otherCanShowQrCode: Boolean = false, val otherCanScanQrCode: Boolean = false, val qrCodeText: String? = null, - val SASModeAvailable: Boolean = false, + val sasModeAvailable: Boolean = false, val isMe: Boolean = false, val canCrossSign: Boolean = false ) : MvRxState @@ -74,7 +74,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( copy( otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(), otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(), - SASModeAvailable = pvr?.isSasSupported().orFalse() + sasModeAvailable = pvr?.isSasSupported().orFalse() ) } } @@ -115,7 +115,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(), otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(), qrCodeText = (qrCodeVerificationTransaction as? QrCodeVerificationTransaction)?.qrCodeText, - SASModeAvailable = pvr?.isSasSupported().orFalse() + sasModeAvailable = pvr?.isSasSupported().orFalse() ) } } diff --git a/vector/src/main/java/im/vector/app/features/html/FontTagHandler.kt b/vector/src/main/java/im/vector/app/features/html/FontTagHandler.kt index 362c8279e1..0c5eff61ae 100644 --- a/vector/src/main/java/im/vector/app/features/html/FontTagHandler.kt +++ b/vector/src/main/java/im/vector/app/features/html/FontTagHandler.kt @@ -34,12 +34,12 @@ class FontTagHandler : SimpleTagHandler() { return ForegroundColorSpan(colorString) } - private fun parseColor(color_name: String): Int { + private fun parseColor(colorName: String): Int { try { - return Color.parseColor(color_name) + return Color.parseColor(colorName) } catch (e: Exception) { // try other w3c colors? - return when (color_name) { + return when (colorName) { "white" -> Color.WHITE "yellow" -> Color.YELLOW "fuchsia" -> Color.parseColor("#FF00FF") diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/CircleView.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/CircleView.kt index e44ce8ee10..d2ada9e7cf 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/CircleView.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/CircleView.kt @@ -108,25 +108,25 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet companion object { val INNER_CIRCLE_RADIUS_PROGRESS: Property = object : Property(Float::class.java, "innerCircleRadiusProgress") { - override operator fun get(`object`: CircleView): Float? { - return `object`.innerCircleRadiusProgress + override operator fun get(o: CircleView): Float? { + return o.innerCircleRadiusProgress } - override operator fun set(`object`: CircleView, value: Float?) { + override operator fun set(o: CircleView, value: Float?) { value?.let { - `object`.innerCircleRadiusProgress = it + o.innerCircleRadiusProgress = it } } } val OUTER_CIRCLE_RADIUS_PROGRESS: Property = object : Property(Float::class.java, "outerCircleRadiusProgress") { - override operator fun get(`object`: CircleView): Float? { - return `object`.outerCircleRadiusProgress + override operator fun get(o: CircleView): Float? { + return o.outerCircleRadiusProgress } - override operator fun set(`object`: CircleView, value: Float?) { + override operator fun set(o: CircleView, value: Float?) { value?.let { - `object`.outerCircleRadiusProgress = it + o.outerCircleRadiusProgress = it } } } diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/DotsView.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/DotsView.kt index 5430bc60fd..c9283c663a 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/DotsView.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/DotsView.kt @@ -186,12 +186,12 @@ class DotsView @JvmOverloads constructor(context: Context, attrs: AttributeSet? private const val OUTER_DOTS_POSITION_ANGLE = 360 / DOTS_COUNT val DOTS_PROGRESS: Property = object : Property(Float::class.java, "dotsProgress") { - override operator fun get(`object`: DotsView): Float? { - return `object`.currentProgress + override operator fun get(o: DotsView): Float? { + return o.currentProgress } - override operator fun set(`object`: DotsView, value: Float?) { - `object`.currentProgress = value!! + override operator fun set(o: DotsView, value: Float?) { + o.currentProgress = value!! } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 7f6dd7b05f..2dc35fb653 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -563,7 +563,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( private fun refreshMyDevice() { session.cryptoService().getUserDevices(session.myUserId).map { DeviceInfo( - user_id = session.myUserId, + userId = session.myUserId, deviceId = it.deviceId, displayName = it.displayName() ) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index bc72f812ff..ae45989a81 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -25,7 +25,6 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.Loading import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import im.vector.app.R import im.vector.app.core.dialogs.ManuallyVerifyDialog import im.vector.app.core.dialogs.PromptPasswordDialog @@ -37,6 +36,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.features.crypto.verification.VerificationBottomSheet import kotlinx.android.synthetic.main.fragment_generic_recycler.* import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import javax.inject.Inject /** @@ -108,7 +108,7 @@ class VectorSettingsDevicesFragment @Inject constructor( } override fun onDeviceClicked(deviceInfo: DeviceInfo) { - DeviceVerificationInfoBottomSheet.newInstance(deviceInfo.user_id ?: "", deviceInfo.deviceId ?: "").show( + DeviceVerificationInfoBottomSheet.newInstance(deviceInfo.userId ?: "", deviceInfo.deviceId ?: "").show( childFragmentManager, "VERIF_INFO" ) From 3f306368081ed302fdc02c72b654a69f72e79d4c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 09:23:08 +0200 Subject: [PATCH 105/257] Matrix SDK is now exported --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 457b18d775..2cbb82fe14 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@ Nightly build: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f6 # New Android SDK -Element is based on a new Android SDK fully written in Kotlin (like Element). In order to make the early development as fast as possible, Element and the new SDK currently share the same git repository. We will make separate repos once the SDK is stable enough. +Element is based on a new Android SDK fully written in Kotlin (like Element). In order to make the early development as fast as possible, Element and the new SDK currently share the same git repository. + +The SDK module is copied to a dedicated repository: https://github.com/matrix-org/matrix-android-sdk2. That way, third party apps can add a regular gradle dependency to use it. So more details on how to do that here: https://github.com/matrix-org/matrix-android-sdk2. # Roadmap From 71de2d9adcc8aaa95eacc1d453b7a08e1764a865 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 09:23:55 +0200 Subject: [PATCH 106/257] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cbb82fe14..9f31e83ef6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Nightly build: [![Buildkite](https://badge.buildkite.com/657d3db27364448d69d54f6 Element is based on a new Android SDK fully written in Kotlin (like Element). In order to make the early development as fast as possible, Element and the new SDK currently share the same git repository. -The SDK module is copied to a dedicated repository: https://github.com/matrix-org/matrix-android-sdk2. That way, third party apps can add a regular gradle dependency to use it. So more details on how to do that here: https://github.com/matrix-org/matrix-android-sdk2. +At each Element release, the SDK module is copied to a dedicated repository: https://github.com/matrix-org/matrix-android-sdk2. That way, third party apps can add a regular gradle dependency to use it. So more details on how to do that here: https://github.com/matrix-org/matrix-android-sdk2. # Roadmap From 66dfcbc2f8052e0df609ba58d4e53f698a7a977e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 10:11:38 +0200 Subject: [PATCH 107/257] Add documentation on the flows --- docs/add_email.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 docs/add_email.md diff --git a/docs/add_email.md b/docs/add_email.md new file mode 100644 index 0000000000..64227418a3 --- /dev/null +++ b/docs/add_email.md @@ -0,0 +1,177 @@ +# Adding an email to an account + +## User enter the email + +> POST https://homeserver.org/_matrix/client/r0/account/3pid/email/requestToken + +```json +{ + "email": "alice@email-provider.org", + "client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh", + "send_attempt": 1 +} +``` + +### The email is already adding to an account + +400 + +```json +{ + "errcode": "M_THREEPID_IN_USE", + "error": "Email is already in use" +} +``` + +### The email is free + +Wording: "We've sent you an email to verify your address. Please follow the instructions there and then click the button below." + +200 + +```json +{ + "sid": "bxyDHuJKsdkjMlTJ" +} +``` + +## User receive an e-mail + +> [homeserver.org] Validate your email +> +> A request to add an email address to your Matrix account has been received. If this was you, please click the link below to confirm adding this email: + https://homeserver.org/_matrix/client/unstable/add_threepid/email/submit_token?token=WUnEhQAmJrXupdEbXgdWvnVIKaGYZFsU&client_secret=TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh&sid=bxyDHuJKsdkjMlTJ +> +> If this was not you, you can safely ignore this email. Thank you. + +## User clicks on the link + +The browser displays the following message: + +> Your email has now been validated, please return to your client. You may now close this window. + +## User returns on Element + +User clicks on CONTINUE + +> POST https://homeserver.org/_matrix/client/r0/account/3pid/add + +```json +{ + "sid": "bxyDHuJKsdkjMlTJ", + "client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh" +} +``` + +401 User Interactive Authentication + +```json +{ + "session": "ppvvnozXCQZFaggUBlHJYPjA", + "flows": [ + { + "stages": [ + "m.login.password" + ] + } + ], + "params": { + } +} +``` + +## User enters his password + +POST https://homeserver.org/_matrix/client/r0/account/3pid/add + +```json +{ + "sid": "bxyDHuJKsdkjMlTJ", + "client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh", + "auth": { + "session": "ppvvnozXCQZFaggUBlHJYPjA", + "type": "m.login.password", + "user": "@benoitx:matrix.org", + "identifier": { + "type": "m.id.user", + "user": "@benoitx:matrix.org" + }, + "password": "weak_password" + } +} +``` + +### The link has not been clicked + +400 + +```json +{ + "errcode": "M_THREEPID_AUTH_FAILED", + "error": "No validated 3pid session found" +} +``` + +### Wrong password + +401 + +```json +{ + "session": "fXHOvoQsPMhEebVqTnIrzZJN", + "flows": [ + { + "stages": [ + "m.login.password" + ] + } + ], + "params": { + }, + "completed":[ + ], + "error": "Invalid password", + "errcode": "M_FORBIDDEN" +} +``` + +### The link has been clicked and the account password is correct + +200 + +```json +{} +``` + +# Remove email + +## User want to remove the email from his account + +> POST https://homeserver.org/_matrix/client/r0/account/3pid/delete + +```json +{ + "medium": "email", + "address": "alice@email-provider.org" +} +``` + +### Email was not bound to an identity server + +200 + +```json +{ + "id_server_unbind_result": "no-support" +} +``` + +### Email was bound to an identity server + +200 + +```json +{ + "id_server_unbind_result": "success" +} +``` From b11eced4f14b179ab0cacd7a4c3bfdf93b228fdb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 11:12:29 +0200 Subject: [PATCH 108/257] Fix a refresh problem on the user avatar --- .../app/core/preference/UserAvatarPreference.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt index e3b4430fe0..3bb50c6284 100755 --- a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt @@ -26,6 +26,7 @@ import im.vector.app.R import im.vector.app.core.extensions.vectorComponent import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.session.user.model.User +import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem class UserAvatarPreference : Preference { @@ -34,6 +35,8 @@ class UserAvatarPreference : Preference { private var avatarRenderer: AvatarRenderer = context.vectorComponent().avatarRenderer() + private var userItem: MatrixItem.UserItem? = null + constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs) @@ -50,9 +53,16 @@ class UserAvatarPreference : Preference { super.onBindViewHolder(holder) mAvatarView = holder.itemView.findViewById(R.id.settings_avatar) mLoadingProgressBar = holder.itemView.findViewById(R.id.avatar_update_progress_bar) + refreshUi() } fun refreshAvatar(user: User) { - mAvatarView?.let { avatarRenderer.render(user.toMatrixItem(), it) } + userItem = user.toMatrixItem() + refreshUi() + } + + private fun refreshUi() { + val safeUserItem = userItem ?: return + mAvatarView?.let { avatarRenderer.render(safeUserItem, it) } } } From 46d3608ccb5c705fea92f7f585cba8fce6d92cbc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Aug 2020 11:25:16 +0200 Subject: [PATCH 109/257] RiotX -> Element --- .../{RiotXFeature => ElementFeature}/globals.xml.ftl | 0 .../templates/{RiotXFeature => ElementFeature}/recipe.xml.ftl | 0 .../root/res/layout/fragment.xml.ftl | 0 .../root/src/app_package/Action.kt.ftl | 0 .../root/src/app_package/Activity.kt.ftl | 0 .../root/src/app_package/Fragment.kt.ftl | 0 .../root/src/app_package/ViewEvents.kt.ftl | 0 .../root/src/app_package/ViewModel.kt.ftl | 0 .../root/src/app_package/ViewState.kt.ftl | 0 tools/templates/{RiotXFeature => ElementFeature}/template.xml | 2 +- tools/templates/configure.sh | 4 ++-- 11 files changed, 3 insertions(+), 3 deletions(-) rename tools/templates/{RiotXFeature => ElementFeature}/globals.xml.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/recipe.xml.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/res/layout/fragment.xml.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/Action.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/Activity.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/Fragment.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/ViewEvents.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/ViewModel.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/root/src/app_package/ViewState.kt.ftl (100%) rename tools/templates/{RiotXFeature => ElementFeature}/template.xml (99%) diff --git a/tools/templates/RiotXFeature/globals.xml.ftl b/tools/templates/ElementFeature/globals.xml.ftl similarity index 100% rename from tools/templates/RiotXFeature/globals.xml.ftl rename to tools/templates/ElementFeature/globals.xml.ftl diff --git a/tools/templates/RiotXFeature/recipe.xml.ftl b/tools/templates/ElementFeature/recipe.xml.ftl similarity index 100% rename from tools/templates/RiotXFeature/recipe.xml.ftl rename to tools/templates/ElementFeature/recipe.xml.ftl diff --git a/tools/templates/RiotXFeature/root/res/layout/fragment.xml.ftl b/tools/templates/ElementFeature/root/res/layout/fragment.xml.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/res/layout/fragment.xml.ftl rename to tools/templates/ElementFeature/root/res/layout/fragment.xml.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/Action.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/Action.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/Action.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/Action.kt.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/Activity.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/Activity.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/Activity.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/Activity.kt.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/Fragment.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/Fragment.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewEvents.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/ViewEvents.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/ViewEvents.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/ViewEvents.kt.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/ViewModel.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/ViewModel.kt.ftl diff --git a/tools/templates/RiotXFeature/root/src/app_package/ViewState.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/ViewState.kt.ftl similarity index 100% rename from tools/templates/RiotXFeature/root/src/app_package/ViewState.kt.ftl rename to tools/templates/ElementFeature/root/src/app_package/ViewState.kt.ftl diff --git a/tools/templates/RiotXFeature/template.xml b/tools/templates/ElementFeature/template.xml similarity index 99% rename from tools/templates/RiotXFeature/template.xml rename to tools/templates/ElementFeature/template.xml index 33d2edfc70..14c718c993 100644 --- a/tools/templates/RiotXFeature/template.xml +++ b/tools/templates/ElementFeature/template.xml @@ -2,7 +2,7 @@