Merge branch 'develop' into feature/fga/text_composer_extract
This commit is contained in:
commit
3df004b035
2
.github/ISSUE_TEMPLATE/release.yml
vendored
2
.github/ISSUE_TEMPLATE/release.yml
vendored
@ -1,7 +1,7 @@
|
||||
name: Release checklist
|
||||
description: Checklist for each release. This template is only for the core team.
|
||||
title: "[Release] Element Android v"
|
||||
labels: [\U0001F680 Release]
|
||||
labels: [🚀 Release]
|
||||
assignees:
|
||||
- bmarty
|
||||
|
||||
|
10
CHANGES.md
10
CHANGES.md
@ -1,3 +1,13 @@
|
||||
Changes in Element v1.3.1 (2021-09-29)
|
||||
======================================
|
||||
|
||||
Bugfixes 🐛
|
||||
----------
|
||||
- Verifying exported E2E keys to provide user feedback when the output is malformed ([#4082](https://github.com/vector-im/element-android/issues/4082))
|
||||
- Fix settings crash when accelerometer not available ([#4103](https://github.com/vector-im/element-android/issues/4103))
|
||||
- Crash while rendering failed message warning ([#4110](https://github.com/vector-im/element-android/issues/4110))
|
||||
|
||||
|
||||
Changes in Element v1.3.0 (2021-09-27)
|
||||
======================================
|
||||
|
||||
|
1
changelog.d/240.feature
Normal file
1
changelog.d/240.feature
Normal file
@ -0,0 +1 @@
|
||||
Android Auto notification support
|
2
changelog.d/3898.bugfix
Normal file
2
changelog.d/3898.bugfix
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes the passphrase screen being incorrectly shown when pressing back on the key verification screen.
|
||||
When the user doesn't have a passphrase set we don't show the passphrase screen.
|
1
changelog.d/3935.bugfix
Normal file
1
changelog.d/3935.bugfix
Normal file
@ -0,0 +1 @@
|
||||
Save button for adding rooms to a space is hidden when scrolling through list of rooms
|
1
changelog.d/4027.feature
Normal file
1
changelog.d/4027.feature
Normal file
@ -0,0 +1 @@
|
||||
Add client base url config to customize permalinks
|
@ -1 +0,0 @@
|
||||
Verifying exported E2E keys to provide user feedback when the output is malformed
|
4
changelog.d/4092.bugfix
Normal file
4
changelog.d/4092.bugfix
Normal file
@ -0,0 +1,4 @@
|
||||
Added changes that will make SearchView in search bar focused by default on opening reaction picker.
|
||||
|
||||
When tapping close icon of SearchView, the SearchView did not collapse therefore added the on close listener
|
||||
which will collapse the SearchView on close.
|
@ -1 +0,0 @@
|
||||
Fix settings crash when accelerometer not available
|
1
changelog.d/4113.misc
Normal file
1
changelog.d/4113.misc
Normal file
@ -0,0 +1 @@
|
||||
Fix release label in the release issue template
|
@ -9,8 +9,8 @@ ext.versions = [
|
||||
|
||||
def gradle = "7.0.2"
|
||||
// Ref: https://kotlinlang.org/releases.html
|
||||
def kotlin = "1.5.30"
|
||||
def kotlinCoroutines = "1.5.1"
|
||||
def kotlin = "1.5.31"
|
||||
def kotlinCoroutines = "1.5.2"
|
||||
def dagger = "2.38.1"
|
||||
def retrofit = "2.9.0"
|
||||
def arrow = "0.8.2"
|
||||
|
2
fastlane/metadata/android/cs-CZ/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/cs-CZ/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Hlavní změny v této verzi: Mnohá vylepšení VoIP a prostorů (stále v beta verzi).
|
||||
Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
Hauptänderungen: Sprachnachrichten standardmäßig aktiviert.
|
||||
Ganze Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Ganze Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/de-DE/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
VoIP und Spaces verbessert
|
||||
Vollständige Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
2
fastlane/metadata/android/en-US/changelogs/40103010.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/40103010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Main changes in this version: Organize your rooms using Spaces! v1.3.1 is fixing a crash which can occurs in v1.3.0.
|
||||
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.3.1
|
@ -1,2 +1,2 @@
|
||||
Põhilised muutused selles versioonis: häälsõnumid on nüüd vaikimisi kasutusel.
|
||||
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/et/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/et/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Põhilised muutused selles versioonis: palju täiendusi kõnede ja veel testjärgus olevas kogukonnakeskuste loogikas.
|
||||
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
تغییرهای اصلی در این نگارش: پیام صوتی به صورت پیشگزیده به کار افتاده.
|
||||
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/fa/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/fa/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
تغییرات اصلی در این نگارش: چندین بهبود در ویپ و فضاها (همچنان در حالت آزمایشی).
|
||||
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
Fő változás ebben a verzióban: Hangüzenetek alapértelmezetten engedélyezettek.
|
||||
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/hu-HU/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/hu-HU/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Fő változás ebben a verzióban: Sok fejlesztés a VoIP és Terek kapcsán (még béta)
|
||||
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
Modifiche principali in questa versione: i messaggi vocali sono attivi in modo predefinito.
|
||||
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/it-IT/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/it-IT/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Modifiche principali in questa versione: molti miglioramenti nel VoIP e negli Spazi (ancora in beta).
|
||||
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
Principais mudanças nesta versão: Mensagem de Voz está habilitada por default.
|
||||
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/pt-BR/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/pt-BR/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Principais mudanças nesta versão: Muitas melhorias em VoIP e Espaços (ainda em beta).
|
||||
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
Основные изменения в этой версии: Голосовое сообщение включено по умолчанию.
|
||||
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/ru-RU/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/ru-RU/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Основные изменения в этой версии: Множество улучшений в VoIP и пространствах (все еще в бета-версии).
|
||||
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
2
fastlane/metadata/android/sq/changelogs/40100100.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100100.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ky version i ri përmban kryesisht ndreqje të metash dhe përmirësime. Dërgimi i një mesazhi tani është shumë i shpejtë.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.10
|
2
fastlane/metadata/android/sq/changelogs/40100110.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100110.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ky version i ri përmban kryesisht përmirësime të ndërfaqes dhe punimit të përdoruesit. Tani mund të ftoni shokë, dhe të krijoni MD shumë shpejt, përmes skanimit të kodesh QR.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.11
|
2
fastlane/metadata/android/sq/changelogs/40100120.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100120.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Paraparje URL-sh, tastierë e re për emoji, aftësi të reja për rregullime dhome, dhe dëborë për Krishtlindje!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.12
|
2
fastlane/metadata/android/sq/changelogs/40100130.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100130.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Paraparje URL-sh, tastierë e re për emoji, aftësi të reja për rregullime dhome, dhe dëborë për Krishtlindje!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.13
|
2
fastlane/metadata/android/sq/changelogs/40100140.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100140.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Përpunim lejesh dhome, temë e çelët/e errët e automatizuar, dhe një dorë ndreqjesh të metash.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.14
|
2
fastlane/metadata/android/sq/changelogs/40100150.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100150.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Mbulim Hyrjesh nga rrjete shoqërorë.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.15
|
2
fastlane/metadata/android/sq/changelogs/40100160.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Mbulim Hyrjesh nga rrjete shoqërorë.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.15 dhe https://github.com/vector-im/element-android/releases/tag/v1.0.16
|
2
fastlane/metadata/android/sq/changelogs/40100170.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40100170.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.0.17
|
2
fastlane/metadata/android/sq/changelogs/40101000.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101000.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Përmirësime për VoIP (thirrje audio dhe video në DM) dhe ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.0
|
2
fastlane/metadata/android/sq/changelogs/40101010.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përmirësime funksionimi dhe ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.1
|
2
fastlane/metadata/android/sq/changelogs/40101020.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101020.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përmirësime funksionimi dhe ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.2
|
2
fastlane/metadata/android/sq/changelogs/40101030.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101030.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përmirësime funksionimi dhe ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.3
|
2
fastlane/metadata/android/sq/changelogs/40101040.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101040.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përmirësime funksionimi dhe ndreqje të metash!
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.4
|
2
fastlane/metadata/android/sq/changelogs/40101050.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101050.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: ndreqje të metash për 1.1.4
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.5
|
2
fastlane/metadata/android/sq/changelogs/40101060.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101060.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: ndreqje të metash për 1.1.5
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.6
|
2
fastlane/metadata/android/sq/changelogs/40101070.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101070.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: mbulim për Hapësira, në fazë beta. Ngjeshje videosh, përpara dërgimi.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.7
|
2
fastlane/metadata/android/sq/changelogs/40101080.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101080.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përmirësime për Hapësira.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.8
|
2
fastlane/metadata/android/sq/changelogs/40101090.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101090.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: shtim mbulimi për rrjetin gitter.im.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.9
|
2
fastlane/metadata/android/sq/changelogs/40101100.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101100.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përditësime teme dhe stili dhe veçori të reja për hapësira.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.10
|
2
fastlane/metadata/android/sq/changelogs/40101110.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101110.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përditësime teme dhe stili dhe veçori të reja për hapësira (ndreqje të mete për 1.1.10)
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.11
|
2
fastlane/metadata/android/sq/changelogs/40101120.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101120.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përditësime teme dhe stili dhe ndreqje e një vithisjeje pas një thirrjeje video
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.12
|
2
fastlane/metadata/android/sq/changelogs/40101130.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101130.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: përditësim kryesisht për qëndrueshmërinë dhe ndreqje të metash.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.13
|
2
fastlane/metadata/android/sq/changelogs/40101140.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101140.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: ndreqje e një problemi rreth mesazhesh të fshehtëzuar.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.14
|
2
fastlane/metadata/android/sq/changelogs/40101150.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101150.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: sendërtim mesazhesh zanore, nën mjedis laboratori.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.15
|
2
fastlane/metadata/android/sq/changelogs/40101160.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40101160.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Ndreqje gabimi, kur dërgohet mesazh i fshehtëzuar, nëse dikush nga dhoma bën dalje prej saj.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
2
fastlane/metadata/android/sq/changelogs/40102000.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40102000.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Mesazh Zanor është i aktivizuar, si parazgjedhje.
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
2
fastlane/metadata/android/sq/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Ndryshimet kryesore në këtë version: Mjaft përmirësime në VoIP dhe Hapësira (ende në beta).
|
||||
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
39
fastlane/metadata/android/sq/full_description.txt
Normal file
39
fastlane/metadata/android/sq/full_description.txt
Normal file
@ -0,0 +1,39 @@
|
||||
Element-i është si aplikacion shkëmbyes i sigurt mesazhesh, ashtu edhe bashkëpunimi prodhimtar ekipi, i cili është ideal për fjalosje në grup, teksa punohet së largët. Ky aplikacion fjalosjeje përdor fshehtëzim skaj-më-skaj për të furnizuar konferencë video, shkëmbim kartelash dhe thirrje me zë të fuqishme.
|
||||
|
||||
<b>Në veçoritë e Element-it përfshihen:</b>
|
||||
- Mjete të thelluara komunikimi internetor
|
||||
- Mesazhe plotësisht të fshehtëzuar, për të lejuar komunikim në nivel korporate, madje edhe për punonjës së largëti
|
||||
- Fjalosje e decentralizuar, bazuar në platformën me burim të hapët Matrix
|
||||
- Shkëmbim i sigurt kartelash, me të dhëna të fshehtëzuara, teksa administrohen projekte
|
||||
- Fjalosje video të llojit VoIP dhe tregim ekrani
|
||||
- Integrim i kollajtë me mjetet tuaja të parapëlqyera të bashkëpunimit internetor, mjete administrimi projektesh, shërbime VoIP dhe aplikacione të tjera shkëmbimi mesazhesh në ekip
|
||||
|
||||
Element-i është plotësisht i ndryshëm nga aplikacione të tjera shkëmbimi mesazhesh dhe bashkëpunimi. Funksionimi i tij bazohet në Matrix, një rrjet i hapët për mesazhe të siguruar dhe komunikim të decentralizuar. Lejon vetëstrehim, për t’u lejuar përdoruesve pronësi dhe kontroll maksimal të të dhënave dhe mesazheve të tyre.
|
||||
|
||||
<b>Privatësi dhe shkëmbim mesazhesh të fshehtëzuar</b>
|
||||
Element-i ju mbron nga reklama të padëshiruara, shfrytëzim të dhënash dhe vatha dixhitale. Ai siguron gjithashtu krejt të dhënat tuaja, komunikime tek-për-tek me video dhe me zë, përmes fshehtëzimi skaj-më-skaj dhe verifikim “cross-signed” pajisjesh.
|
||||
|
||||
Element-i ju jep kontrollin e privatësisë tuaj, teksa ju lejon të komunikoni në mënyrë të siguruar me këdo në rrjetin Matrix, ose me mjete të tjera bashkëpunimi në shkallë biznesi, duke u integruar me aplikacione të tillë si Slack.
|
||||
|
||||
<b>Element-i mund të vetëstrehohet</b>
|
||||
Për të lejuar më tepër kontroll mbi të dhënat dhe bisedat tuaja rezervat, Element-i mund të vetëstrehohet, ose mund të zgjidhni cilëndo strehë të bazuar në Matrix - standardi për komunikim me burim të hapët, të decentralizuar. Element-i ju jep privatësi, pajtueshmëri sigurie dhe zhdërvjelltësi integrimesh.
|
||||
|
||||
<b>Jini zot i të dhënave tuaja</b>
|
||||
Ju vendosni ku të mbahen të dhënat dhe mesazhet tuaja. Pa rrezikun e shfrytëzimit të të dhënave apo hyrjes në to nga palë të treta.
|
||||
|
||||
Element-i ju vë ju në kontroll përmes rrugësh të ndryshme:
|
||||
1. Merrni një llogari falas te shërbyesi publik matrix.org strehuar nga zhvillues të Matrix-it, ose zgjidhni prej mijëra shërbyesish publikë të strehuar nga vullnetarë
|
||||
2. Vetëstrehoni llogarinë tuaj duke xhiruar një shërbyes në infrastrukturën tuaj TI
|
||||
3. Regjistrohuni për një llogari në një shërbyes vetjak, thjesht duke u pajtuar te platforma Element Matrix Services e strehimeve
|
||||
|
||||
<b>Shkëmbim mesazhesh dhe bashkëpunim me burim të hapët</b>
|
||||
Mund të fjaloseni me këdo në rrjetin Matrix, qoftë kur përdorin Element, një tjetër aplikacion Matrix, apo edhe kur përdorin një tjetër aplikacion shkëmbimi mesazhesh.
|
||||
|
||||
<b>Super i sigurt</b>
|
||||
Fshehtëzim i njëmendtë skaj-më-skaj (vetëm ata te biseda mund të shfshehtëzojnë mesazhe), dhe verifikim “cross-signed” pajisjesh.
|
||||
|
||||
<b>Komunikim dhe integrim i plotë</b>
|
||||
Shkëmbim mesazhesh, thirrje me zë dhe me video, shkëmbim kartelash, tregim ekrani dhe një grup i tërë integrimesh, robotësh dhe widget-esh. Krijoni dhoma, bashkësi, mbani lidhjet dhe mbaroni punë.
|
||||
|
||||
<b>Rifillojani atje ku e latë</b>
|
||||
Jini në dijeni, kudo ku gjendeni, me historik plotësisht të njëkohësuar mesazhesh nëpër krejt pajisjet tuaja dhe në internet te https://app.element.io
|
1
fastlane/metadata/android/sq/short_description.txt
Normal file
1
fastlane/metadata/android/sq/short_description.txt
Normal file
@ -0,0 +1 @@
|
||||
Mesazhe grupi - mesazhe, fjalosje në grup dhe thirrje me video, të fshehtëzuara
|
@ -1 +1 @@
|
||||
Element - Shkëmbyes I Sigurt Mesazhesh
|
||||
Element - Shkëmbyes i Sigurt Mesazhesh
|
||||
|
@ -1,2 +1,2 @@
|
||||
Основні зміни в цій версії: голосові повідомлення типово увімкнено.
|
||||
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/uk/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/uk/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Основні зміни в цій версії: багато вдосконалень VoIP і просторів (досі бета)
|
||||
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -1,2 +1,2 @@
|
||||
此版本中的主要更改:默认启用语音消息。
|
||||
完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
||||
完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
||||
|
2
fastlane/metadata/android/zh-CN/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/zh-CN/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
这个版本的主要变化:VoIP和空间的许多改进(仍在测试中)。
|
||||
完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
2
fastlane/metadata/android/zh-TW/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/zh-TW/changelogs/40102010.txt
Normal file
@ -0,0 +1,2 @@
|
||||
此版本中的主要變動:對 VoIP 與空間功能的諸多改善(仍在測試中)。
|
||||
完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
@ -31,7 +31,7 @@ android {
|
||||
// that the app's state is completely cleared between tests.
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
|
||||
buildConfigField "String", "SDK_VERSION", "\"1.3.1\""
|
||||
buildConfigField "String", "SDK_VERSION", "\"1.3.2\""
|
||||
|
||||
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
|
||||
resValue "string", "git_sdk_revision", "\"${gitRevision()}\""
|
||||
|
@ -32,8 +32,16 @@ data class MatrixConfiguration(
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
),
|
||||
/**
|
||||
* Optional proxy to connect to the matrix servers
|
||||
* You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port)
|
||||
* Optional base url to create client permalinks (eg. https://www.example.com/#/) instead of Matrix ones (matrix.to links).
|
||||
* Do not forget to add the "#" which is required by the permalink parser.
|
||||
*
|
||||
* Note: this field is only used for permalinks creation, you will also have to edit the string-array `permalink_supported_hosts` in the config file
|
||||
* and add it to your manifest to handle these links in the application.
|
||||
*/
|
||||
val clientPermalinkBaseUrl: String? = null,
|
||||
/**
|
||||
* Optional proxy to connect to the matrix servers.
|
||||
* You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port).
|
||||
*/
|
||||
val proxy: Proxy? = null,
|
||||
/**
|
||||
@ -47,7 +55,7 @@ data class MatrixConfiguration(
|
||||
) {
|
||||
|
||||
/**
|
||||
* Can be implemented by your Application class
|
||||
* Can be implemented by your Application class.
|
||||
*/
|
||||
interface Provider {
|
||||
fun providesMatrixConfiguration(): MatrixConfiguration
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.session.permalinks
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
/**
|
||||
* Mapping of an input URI to a matrix.to compliant URI.
|
||||
*/
|
||||
object MatrixToConverter {
|
||||
|
||||
/**
|
||||
* Try to convert a URL from an element web instance or from a client permalink to a matrix.to url.
|
||||
* To be successfully converted, URL path should contain one of the [SUPPORTED_PATHS].
|
||||
* Examples:
|
||||
* - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
|
||||
* - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
|
||||
* - https://www.example.org/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
|
||||
*/
|
||||
fun convert(uri: Uri): Uri? {
|
||||
val uriString = uri.toString()
|
||||
|
||||
return when {
|
||||
// URL is already a matrix.to
|
||||
uriString.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> uri
|
||||
// Web or client url
|
||||
SUPPORTED_PATHS.any { it in uriString } -> {
|
||||
val path = SUPPORTED_PATHS.first { it in uriString }
|
||||
Uri.parse(PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path))
|
||||
}
|
||||
// URL is not supported
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private val SUPPORTED_PATHS = listOf(
|
||||
"/#/room/",
|
||||
"/#/user/",
|
||||
"/#/group/"
|
||||
)
|
||||
}
|
@ -26,6 +26,7 @@ import java.net.URLDecoder
|
||||
* This class turns a uri to a [PermalinkData]
|
||||
* element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks
|
||||
* or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org)
|
||||
* or client permalinks (e.g. <clientPermalinkBaseUrl>user/@chagai95:matrix.org)
|
||||
*/
|
||||
object PermalinkParser {
|
||||
|
||||
@ -42,13 +43,15 @@ object PermalinkParser {
|
||||
* https://github.com/matrix-org/matrix-doc/blob/master/proposals/1704-matrix.to-permalinks.md
|
||||
*/
|
||||
fun parse(uri: Uri): PermalinkData {
|
||||
if (!uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE)) {
|
||||
return PermalinkData.FallbackLink(uri)
|
||||
}
|
||||
// the client or element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the
|
||||
// mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid
|
||||
// so convert URI to matrix.to to simplify parsing process
|
||||
val matrixToUri = MatrixToConverter.convert(uri) ?: return PermalinkData.FallbackLink(uri)
|
||||
|
||||
// We can't use uri.fragment as it is decoding to early and it will break the parsing
|
||||
// of parameters that represents url (like signurl)
|
||||
val fragment = uri.toString().substringAfter("#") // uri.fragment
|
||||
if (fragment.isNullOrEmpty()) {
|
||||
val fragment = matrixToUri.toString().substringAfter("#") // uri.fragment
|
||||
if (fragment.isEmpty()) {
|
||||
return PermalinkData.FallbackLink(uri)
|
||||
}
|
||||
val safeFragment = fragment.substringBefore('?')
|
||||
@ -61,20 +64,14 @@ object PermalinkParser {
|
||||
.map { URLDecoder.decode(it, "UTF-8") }
|
||||
.take(2)
|
||||
|
||||
// the element-based domain permalinks (e.g. https://app.element.io/#/user/@chagai95:matrix.org) don't have the
|
||||
// mxid in the first param (like matrix.to does - https://matrix.to/#/@chagai95:matrix.org) but rather in the second after /user/ so /user/mxid
|
||||
var identifier = params.getOrNull(0)
|
||||
if (identifier.equals("user")) {
|
||||
identifier = params.getOrNull(1)
|
||||
}
|
||||
|
||||
val identifier = params.getOrNull(0)
|
||||
val extraParameter = params.getOrNull(1)
|
||||
return when {
|
||||
identifier.isNullOrEmpty() -> PermalinkData.FallbackLink(uri)
|
||||
MatrixPatterns.isUserId(identifier) -> PermalinkData.UserLink(userId = identifier)
|
||||
MatrixPatterns.isGroupId(identifier) -> PermalinkData.GroupLink(groupId = identifier)
|
||||
MatrixPatterns.isRoomId(identifier) -> {
|
||||
handleRoomIdCase(fragment, identifier, uri, extraParameter, viaQueryParameters)
|
||||
handleRoomIdCase(fragment, identifier, matrixToUri, extraParameter, viaQueryParameters)
|
||||
}
|
||||
MatrixPatterns.isRoomAlias(identifier) -> {
|
||||
PermalinkData.RoomLink(
|
||||
@ -125,12 +122,13 @@ object PermalinkParser {
|
||||
}
|
||||
}
|
||||
|
||||
private fun safeExtractParams(fragment: String) = fragment.substringAfter("?").split('&').mapNotNull {
|
||||
val splitNameValue = it.split("=")
|
||||
if (splitNameValue.size == 2) {
|
||||
Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8"))
|
||||
} else null
|
||||
}
|
||||
private fun safeExtractParams(fragment: String) =
|
||||
fragment.substringAfter("?").split('&').mapNotNull {
|
||||
val splitNameValue = it.split("=")
|
||||
if (splitNameValue.size == 2) {
|
||||
Pair(splitNameValue[0], URLDecoder.decode(splitNameValue[1], "UTF-8"))
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun String.getViaParameters(): List<String> {
|
||||
return UrlQuerySanitizer(this)
|
||||
@ -138,9 +136,7 @@ object PermalinkParser {
|
||||
.filter {
|
||||
it.mParameter == "via"
|
||||
}.map {
|
||||
it.mValue.let {
|
||||
URLDecoder.decode(it, "UTF-8")
|
||||
}
|
||||
URLDecoder.decode(it.mValue, "UTF-8")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ package org.matrix.android.sdk.api.session.permalinks
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
|
||||
/**
|
||||
* Useful methods to create Matrix permalink (matrix.to links).
|
||||
* Useful methods to create permalink (like matrix.to links or client permalinks).
|
||||
* See [org.matrix.android.sdk.api.MatrixConfiguration.clientPermalinkBaseUrl] to setup a custom permalink base url.
|
||||
*/
|
||||
interface PermalinkService {
|
||||
|
||||
@ -32,10 +33,11 @@ interface PermalinkService {
|
||||
* Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org"
|
||||
*
|
||||
* @param event the event
|
||||
* @param forceMatrixTo whether we should force using matrix.to base URL
|
||||
*
|
||||
* @return the permalink, or null in case of error
|
||||
*/
|
||||
fun createPermalink(event: Event): String?
|
||||
fun createPermalink(event: Event, forceMatrixTo: Boolean = false): String?
|
||||
|
||||
/**
|
||||
* Creates a permalink for an id (can be a user Id, etc.).
|
||||
@ -43,18 +45,21 @@ interface PermalinkService {
|
||||
* Ex: "https://matrix.to/#/@benoit:matrix.org"
|
||||
*
|
||||
* @param id the id
|
||||
* @param forceMatrixTo whether we should force using matrix.to base URL
|
||||
*
|
||||
* @return the permalink, or null in case of error
|
||||
*/
|
||||
fun createPermalink(id: String): String?
|
||||
fun createPermalink(id: String, forceMatrixTo: Boolean = false): String?
|
||||
|
||||
/**
|
||||
* Creates a permalink for a roomId, including the via parameters
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param forceMatrixTo whether we should force using matrix.to base URL
|
||||
*
|
||||
* @return the permalink, or null in case of error
|
||||
*/
|
||||
fun createRoomPermalink(roomId: String, viaServers: List<String>? = null): String?
|
||||
fun createRoomPermalink(roomId: String, viaServers: List<String>? = null, forceMatrixTo: Boolean = false): String?
|
||||
|
||||
/**
|
||||
* Creates a permalink for an event. If you have an event you can use [createPermalink]
|
||||
@ -62,10 +67,11 @@ interface PermalinkService {
|
||||
*
|
||||
* @param roomId the id of the room
|
||||
* @param eventId the id of the event
|
||||
* @param forceMatrixTo whether we should force using matrix.to base URL
|
||||
*
|
||||
* @return the permalink
|
||||
*/
|
||||
fun createPermalink(roomId: String, eventId: String): String
|
||||
fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean = false): String
|
||||
|
||||
/**
|
||||
* Extract the linked id from the universal link
|
||||
|
@ -18,33 +18,29 @@ package org.matrix.android.sdk.internal.session.permalinks
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultPermalinkService @Inject constructor(
|
||||
private val permalinkFactory: PermalinkFactory
|
||||
) : PermalinkService {
|
||||
|
||||
override fun createPermalink(event: Event): String? {
|
||||
return permalinkFactory.createPermalink(event)
|
||||
override fun createPermalink(event: Event, forceMatrixTo: Boolean): String? {
|
||||
return permalinkFactory.createPermalink(event, forceMatrixTo)
|
||||
}
|
||||
|
||||
override fun createPermalink(id: String): String? {
|
||||
return permalinkFactory.createPermalink(id)
|
||||
override fun createPermalink(id: String, forceMatrixTo: Boolean): String? {
|
||||
return permalinkFactory.createPermalink(id, forceMatrixTo)
|
||||
}
|
||||
|
||||
override fun createRoomPermalink(roomId: String, viaServers: List<String>?): String? {
|
||||
return permalinkFactory.createRoomPermalink(roomId, viaServers)
|
||||
override fun createRoomPermalink(roomId: String, viaServers: List<String>?, forceMatrixTo: Boolean): String? {
|
||||
return permalinkFactory.createRoomPermalink(roomId, viaServers, forceMatrixTo)
|
||||
}
|
||||
|
||||
override fun createPermalink(roomId: String, eventId: String): String {
|
||||
return permalinkFactory.createPermalink(roomId, eventId)
|
||||
override fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String {
|
||||
return permalinkFactory.createPermalink(roomId, eventId, forceMatrixTo)
|
||||
}
|
||||
|
||||
override fun getLinkedId(url: String): String? {
|
||||
return url
|
||||
.takeIf { it.startsWith(MATRIX_TO_URL_BASE) }
|
||||
?.substring(MATRIX_TO_URL_BASE.length)
|
||||
?.substringBeforeLast("?")
|
||||
return permalinkFactory.getLinkedId(url)
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,11 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.permalinks
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
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.permalinks.PermalinkService.Companion.MATRIX_TO_URL_BASE
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import javax.inject.Inject
|
||||
@ -24,28 +28,44 @@ import javax.inject.Inject
|
||||
internal class PermalinkFactory @Inject constructor(
|
||||
@UserId
|
||||
private val userId: String,
|
||||
private val viaParameterFinder: ViaParameterFinder
|
||||
private val viaParameterFinder: ViaParameterFinder,
|
||||
private val matrixConfiguration: MatrixConfiguration
|
||||
) {
|
||||
|
||||
fun createPermalink(event: Event): String? {
|
||||
fun createPermalink(event: Event, forceMatrixTo: Boolean): String? {
|
||||
if (event.roomId.isNullOrEmpty() || event.eventId.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
return createPermalink(event.roomId, event.eventId)
|
||||
return createPermalink(event.roomId, event.eventId, forceMatrixTo)
|
||||
}
|
||||
|
||||
fun createPermalink(id: String): String? {
|
||||
return if (id.isEmpty()) {
|
||||
null
|
||||
} else MATRIX_TO_URL_BASE + escape(id)
|
||||
fun createPermalink(id: String, forceMatrixTo: Boolean): String? {
|
||||
return when {
|
||||
id.isEmpty() -> null
|
||||
!useClientFormat(forceMatrixTo) -> MATRIX_TO_URL_BASE + escape(id)
|
||||
else -> {
|
||||
buildString {
|
||||
append(matrixConfiguration.clientPermalinkBaseUrl)
|
||||
when {
|
||||
MatrixPatterns.isRoomId(id) || MatrixPatterns.isRoomAlias(id) -> append(ROOM_PATH)
|
||||
MatrixPatterns.isUserId(id) -> append(USER_PATH)
|
||||
MatrixPatterns.isGroupId(id) -> append(GROUP_PATH)
|
||||
}
|
||||
append(escape(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createRoomPermalink(roomId: String, via: List<String>? = null): String? {
|
||||
fun createRoomPermalink(roomId: String, via: List<String>? = null, forceMatrixTo: Boolean): String? {
|
||||
return if (roomId.isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
buildString {
|
||||
append(MATRIX_TO_URL_BASE)
|
||||
append(baseUrl(forceMatrixTo))
|
||||
if (useClientFormat(forceMatrixTo)) {
|
||||
append(ROOM_PATH)
|
||||
}
|
||||
append(escape(roomId))
|
||||
append(
|
||||
via?.takeIf { it.isNotEmpty() }?.let { viaParameterFinder.asUrlViaParameters(it) }
|
||||
@ -55,16 +75,34 @@ internal class PermalinkFactory @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun createPermalink(roomId: String, eventId: String): String {
|
||||
return MATRIX_TO_URL_BASE + escape(roomId) + "/" + escape(eventId) + viaParameterFinder.computeViaParams(userId, roomId)
|
||||
fun createPermalink(roomId: String, eventId: String, forceMatrixTo: Boolean): String {
|
||||
return buildString {
|
||||
append(baseUrl(forceMatrixTo))
|
||||
if (useClientFormat(forceMatrixTo)) {
|
||||
append(ROOM_PATH)
|
||||
}
|
||||
append(escape(roomId))
|
||||
append("/")
|
||||
append(escape(eventId))
|
||||
append(viaParameterFinder.computeViaParams(userId, roomId))
|
||||
}
|
||||
}
|
||||
|
||||
fun getLinkedId(url: String): String? {
|
||||
val isSupported = url.startsWith(MATRIX_TO_URL_BASE)
|
||||
|
||||
return if (isSupported) {
|
||||
url.substring(MATRIX_TO_URL_BASE.length)
|
||||
} else null
|
||||
val clientBaseUrl = matrixConfiguration.clientPermalinkBaseUrl
|
||||
return when {
|
||||
url.startsWith(MATRIX_TO_URL_BASE) -> url.substring(MATRIX_TO_URL_BASE.length)
|
||||
clientBaseUrl != null && url.startsWith(clientBaseUrl) -> {
|
||||
when (PermalinkParser.parse(url)) {
|
||||
is PermalinkData.GroupLink -> url.substring(clientBaseUrl.length + GROUP_PATH.length)
|
||||
is PermalinkData.RoomLink -> url.substring(clientBaseUrl.length + ROOM_PATH.length)
|
||||
is PermalinkData.UserLink -> url.substring(clientBaseUrl.length + USER_PATH.length)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
?.substringBeforeLast("?")
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,4 +124,28 @@ internal class PermalinkFactory @Inject constructor(
|
||||
private fun unescape(id: String): String {
|
||||
return id.replace("%2F", "/")
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permalink base URL according to the potential one in [MatrixConfiguration.clientPermalinkBaseUrl]
|
||||
* and the [forceMatrixTo] parameter.
|
||||
*
|
||||
* @param forceMatrixTo whether we should force using matrix.to base URL.
|
||||
*
|
||||
* @return the permalink base URL.
|
||||
*/
|
||||
private fun baseUrl(forceMatrixTo: Boolean): String {
|
||||
return matrixConfiguration.clientPermalinkBaseUrl
|
||||
?.takeUnless { forceMatrixTo }
|
||||
?: MATRIX_TO_URL_BASE
|
||||
}
|
||||
|
||||
private fun useClientFormat(forceMatrixTo: Boolean): Boolean {
|
||||
return !forceMatrixTo && matrixConfiguration.clientPermalinkBaseUrl != null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ROOM_PATH = "room/"
|
||||
private const val USER_PATH = "user/"
|
||||
private const val GROUP_PATH = "group/"
|
||||
}
|
||||
}
|
||||
|
@ -165,8 +165,8 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
newBodyAutoMarkdown: Boolean,
|
||||
msgType: String,
|
||||
compatibilityText: String): Event {
|
||||
val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "")
|
||||
val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it) } ?: ""
|
||||
val permalink = permalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "", false)
|
||||
val userLink = originalEvent.root.senderId?.let { permalinkFactory.createPermalink(it, false) } ?: ""
|
||||
|
||||
val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.isReply())
|
||||
val replyFormatted = REPLY_PATTERN.format(
|
||||
@ -350,9 +350,9 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
autoMarkdown: Boolean): Event? {
|
||||
// Fallbacks and event representation
|
||||
// TODO Add error/warning logs when any of this is null
|
||||
val permalink = permalinkFactory.createPermalink(eventReplied.root) ?: return null
|
||||
val permalink = permalinkFactory.createPermalink(eventReplied.root, false) ?: return null
|
||||
val userId = eventReplied.root.senderId ?: return null
|
||||
val userLink = permalinkFactory.createPermalink(userId) ?: return null
|
||||
val userLink = permalinkFactory.createPermalink(userId, false) ?: return null
|
||||
|
||||
val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.isReply())
|
||||
val replyFormatted = REPLY_PATTERN.format(
|
||||
|
@ -39,7 +39,7 @@ sealed class InitialSyncStrategy {
|
||||
* Limit to reach to decide to split the init sync response into smaller files
|
||||
* Empiric value: 1 megabytes
|
||||
*/
|
||||
val minSizeToSplit: Long = 1024 * 1024,
|
||||
val minSizeToSplit: Long = 1_048_576, // 1024 * 1024
|
||||
/**
|
||||
* Limit per room to reach to decide to store a join room ephemeral Events into a file
|
||||
* Empiric value: 1 kilobytes
|
||||
|
@ -59,24 +59,6 @@ else
|
||||
removeShortDes_si=1
|
||||
fi
|
||||
|
||||
if [[ -f "./fastlane/metadata/android/sq/short_description.txt" ]]; then
|
||||
echo "It appears that file ./fastlane/metadata/android/sq/short_description.txt now exists. This can be removed."
|
||||
removeShortDes_sq=0
|
||||
else
|
||||
echo "Copy default short description to ./fastlane/metadata/android/sq"
|
||||
cp ./fastlane/metadata/android/en-US/short_description.txt ./fastlane/metadata/android/sq
|
||||
removeShortDes_sq=1
|
||||
fi
|
||||
|
||||
if [[ -f "./fastlane/metadata/android/sq/full_description.txt" ]]; then
|
||||
echo "It appears that file ./fastlane/metadata/android/sq/full_description.txt now exists. This can be removed."
|
||||
removeFullDes_sq=0
|
||||
else
|
||||
echo "Copy default full description to ./fastlane/metadata/android/sq"
|
||||
cp ./fastlane/metadata/android/en-US/full_description.txt ./fastlane/metadata/android/sq
|
||||
removeFullDes_sq=1
|
||||
fi
|
||||
|
||||
if [[ -f "./fastlane/metadata/android/th/full_description.txt" ]]; then
|
||||
echo "It appears that file ./fastlane/metadata/android/th/full_description.txt now exists. This can be removed."
|
||||
removeFullDes_th=0
|
||||
@ -117,18 +99,10 @@ if [[ ${removeShortDes_si} -eq 1 ]]; then
|
||||
rm ./fastlane/metadata/android/si-LK/short_description.txt
|
||||
fi
|
||||
|
||||
if [[ ${removeShortDes_sq} -eq 1 ]]; then
|
||||
rm ./fastlane/metadata/android/sq/short_description.txt
|
||||
fi
|
||||
|
||||
if [[ ${removeFullDes_th} -eq 1 ]]; then
|
||||
rm ./fastlane/metadata/android/th/full_description.txt
|
||||
fi
|
||||
|
||||
if [[ ${removeFullDes_sq} -eq 1 ]]; then
|
||||
rm ./fastlane/metadata/android/sq/full_description.txt
|
||||
fi
|
||||
|
||||
if [[ ${removeFullDes_vi} -eq 1 ]]; then
|
||||
rm ./fastlane/metadata/android/vi/full_description.txt
|
||||
fi
|
||||
|
@ -14,7 +14,7 @@ kapt {
|
||||
// Note: 2 digits max for each value
|
||||
ext.versionMajor = 1
|
||||
ext.versionMinor = 3
|
||||
ext.versionPatch = 1
|
||||
ext.versionPatch = 2
|
||||
|
||||
static def getGitTimestamp() {
|
||||
def cmd = 'git show -s --format=%ct'
|
||||
@ -412,7 +412,7 @@ dependencies {
|
||||
implementation 'com.nulab-inc:zxcvbn:1.5.2'
|
||||
|
||||
// To convert voice message on old platforms
|
||||
implementation 'com.arthenica:ffmpeg-kit-audio:4.4.LTS'
|
||||
implementation 'com.arthenica:ffmpeg-kit-audio:4.5.LTS'
|
||||
|
||||
// Alerter
|
||||
implementation 'com.tapadoo.android:alerter:7.0.1'
|
||||
@ -420,7 +420,7 @@ dependencies {
|
||||
implementation 'com.otaliastudios:autocomplete:1.1.0'
|
||||
|
||||
// Shake detection
|
||||
implementation 'com.squareup:seismic:1.0.2'
|
||||
implementation 'com.squareup:seismic:1.0.3'
|
||||
|
||||
// Image Loading
|
||||
implementation libs.github.bigImageViewer
|
||||
|
@ -83,6 +83,10 @@
|
||||
android:name="android.max_aspect"
|
||||
android:value="9.9" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc" />
|
||||
|
||||
<activity
|
||||
android:name=".features.MainActivity"
|
||||
android:theme="@style/Theme.Vector.Launcher" />
|
||||
@ -105,8 +109,8 @@
|
||||
<activity android:name=".features.home.HomeActivity" />
|
||||
<activity
|
||||
android:name=".features.login.LoginActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:enabled="@bool/useLoginV1"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Add intent filter to handle redirection URL after SSO login in external browser -->
|
||||
<intent-filter>
|
||||
@ -122,8 +126,8 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".features.login2.LoginActivity2"
|
||||
android:launchMode="singleTask"
|
||||
android:enabled="@bool/useLoginV2"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Add intent filter to handle redirection URL after SSO login in external browser -->
|
||||
<intent-filter>
|
||||
@ -180,7 +184,12 @@
|
||||
<activity android:name=".features.createdirect.CreateDirectRoomActivity" />
|
||||
<activity android:name=".features.invite.InviteUsersToRoomActivity" />
|
||||
<activity android:name=".features.webview.VectorWebViewActivity" />
|
||||
<activity android:name=".features.link.LinkHandlerActivity">
|
||||
|
||||
<!-- Activity to intercept links coming from a web instance -->
|
||||
<activity
|
||||
android:name=".features.link.LinkHandlerActivity"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
@ -196,6 +205,32 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Activity alias for matrix.to or element permalinks -->
|
||||
<activity-alias
|
||||
android:name=".features.permalink.PermalinkHandlerActivity"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:targetActivity=".features.link.LinkHandlerActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="matrix.to" />
|
||||
<data
|
||||
android:host="user"
|
||||
android:scheme="element" />
|
||||
<data
|
||||
android:host="room"
|
||||
android:scheme="element" />
|
||||
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name=".features.share.IncomingShareActivity"
|
||||
android:parentActivityName=".features.home.HomeActivity">
|
||||
@ -230,27 +265,6 @@
|
||||
<activity
|
||||
android:name=".features.signout.soft.SoftLogoutActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity
|
||||
android:name=".features.permalink.PermalinkHandlerActivity"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="matrix.to" />
|
||||
<data
|
||||
android:host="user"
|
||||
android:scheme="element" />
|
||||
<data
|
||||
android:host="room"
|
||||
android:scheme="element" />
|
||||
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".features.roommemberprofile.RoomMemberProfileActivity"
|
||||
@ -271,12 +285,12 @@
|
||||
android:name=".features.attachments.preview.AttachmentsPreviewActivity"
|
||||
android:theme="@style/Theme.Vector.Black.AttachmentsPreview" />
|
||||
<activity
|
||||
android:supportsPictureInPicture="true"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||
android:name=".features.call.VectorCallActivity"
|
||||
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity=".features.call.VectorCallActivity"
|
||||
android:excludeFromRecents="true" />
|
||||
android:supportsPictureInPicture="true"
|
||||
android:taskAffinity=".features.call.VectorCallActivity" />
|
||||
<!-- PIP Support https://developer.android.com/guide/topics/ui/picture-in-picture -->
|
||||
<activity
|
||||
android:name=".features.call.conference.VectorJitsiActivity"
|
||||
|
@ -62,7 +62,6 @@ import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||
import im.vector.app.features.media.BigImageViewerActivity
|
||||
import im.vector.app.features.media.VectorAttachmentViewerActivity
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import im.vector.app.features.permalink.PermalinkHandlerActivity
|
||||
import im.vector.app.features.pin.PinLocker
|
||||
import im.vector.app.features.qrcode.QrCodeScannerActivity
|
||||
import im.vector.app.features.rageshake.BugReportActivity
|
||||
@ -155,7 +154,6 @@ interface ScreenComponent {
|
||||
fun inject(activity: CreateDirectRoomActivity)
|
||||
fun inject(activity: IncomingShareActivity)
|
||||
fun inject(activity: SoftLogoutActivity)
|
||||
fun inject(activity: PermalinkHandlerActivity)
|
||||
fun inject(activity: QrCodeScannerActivity)
|
||||
fun inject(activity: DebugMenuActivity)
|
||||
fun inject(activity: SharedSecureStorageActivity)
|
||||
|
@ -27,6 +27,7 @@ import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setAttributeTintedImageResource
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
|
||||
/**
|
||||
@ -62,7 +63,7 @@ abstract class BottomSheetRadioActionItem : VectorEpoxyModel<BottomSheetRadioAct
|
||||
holder.descriptionText.setTextOrHide(description)
|
||||
|
||||
if (selected) {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_on))
|
||||
holder.radioImage.setAttributeTintedImageResource(R.drawable.ic_radio_on, R.attr.colorPrimary)
|
||||
holder.radioImage.contentDescription = holder.view.context.getString(R.string.a11y_checked)
|
||||
} else {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_off))
|
||||
|
@ -27,6 +27,7 @@ import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setAttributeTintedImageResource
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_radio)
|
||||
abstract class RadioButtonItem : VectorEpoxyModel<RadioButtonItem.Holder>() {
|
||||
@ -54,7 +55,7 @@ abstract class RadioButtonItem : VectorEpoxyModel<RadioButtonItem.Holder>() {
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_on))
|
||||
holder.radioImage.setAttributeTintedImageResource(R.drawable.ic_radio_on, R.attr.colorPrimary)
|
||||
holder.radioImage.contentDescription = holder.view.context.getString(R.string.a11y_checked)
|
||||
} else {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_off))
|
||||
|
@ -22,9 +22,14 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
/**
|
||||
* Remove left margin of a SearchView
|
||||
@ -58,3 +63,20 @@ fun ImageView.setDrawableOrHide(drawableRes: Drawable?) {
|
||||
setImageDrawable(drawableRes)
|
||||
isVisible = drawableRes != null
|
||||
}
|
||||
|
||||
fun View.setAttributeTintedBackground(@DrawableRes drawableRes: Int, @AttrRes tint: Int) {
|
||||
val drawable = ContextCompat.getDrawable(context, drawableRes)!!
|
||||
DrawableCompat.setTint(drawable, ThemeUtils.getColor(context, tint))
|
||||
background = drawable
|
||||
}
|
||||
|
||||
fun ImageView.setAttributeTintedImageResource(@DrawableRes drawableRes: Int, @AttrRes tint: Int) {
|
||||
val drawable = ContextCompat.getDrawable(context, drawableRes)!!
|
||||
DrawableCompat.setTint(drawable, ThemeUtils.getColor(context, tint))
|
||||
setImageDrawable(drawable)
|
||||
}
|
||||
|
||||
fun View.setAttributeBackground(@AttrRes attributeId: Int) {
|
||||
val attribute = ThemeUtils.getAttribute(context, attributeId)!!
|
||||
setBackgroundResource(attribute.resourceId)
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
setState {
|
||||
copy(userId = session.myUserId)
|
||||
}
|
||||
@ -167,10 +166,14 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
|
||||
if (state.checkingSSSSAction is Loading) return@withState // ignore
|
||||
when (state.step) {
|
||||
SharedSecureStorageViewState.Step.EnterKey -> {
|
||||
setState {
|
||||
copy(
|
||||
step = SharedSecureStorageViewState.Step.EnterPassphrase
|
||||
)
|
||||
if (state.hasPassphrase) {
|
||||
setState {
|
||||
copy(
|
||||
step = SharedSecureStorageViewState.Step.EnterPassphrase
|
||||
)
|
||||
}
|
||||
} else {
|
||||
_viewEvents.post(SharedSecureStorageViewEvent.Dismiss)
|
||||
}
|
||||
}
|
||||
SharedSecureStorageViewState.Step.ResetAll -> {
|
||||
|
@ -51,6 +51,9 @@ import im.vector.app.features.navigation.Navigator
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
import im.vector.app.features.permalink.NavigationInterceptor
|
||||
import im.vector.app.features.permalink.PermalinkHandler
|
||||
import im.vector.app.features.permalink.PermalinkHandler.Companion.MATRIX_TO_CUSTOM_SCHEME_URL_BASE
|
||||
import im.vector.app.features.permalink.PermalinkHandler.Companion.ROOM_LINK_PREFIX
|
||||
import im.vector.app.features.permalink.PermalinkHandler.Companion.USER_LINK_PREFIX
|
||||
import im.vector.app.features.popup.DefaultVectorAlert
|
||||
import im.vector.app.features.popup.PopupAlertManager
|
||||
import im.vector.app.features.popup.VerificationVectorAlert
|
||||
@ -272,20 +275,19 @@ class HomeActivity :
|
||||
private fun handleIntent(intent: Intent?) {
|
||||
intent?.dataString?.let { deepLink ->
|
||||
val resolvedLink = when {
|
||||
deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> deepLink
|
||||
deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> {
|
||||
// This is a bit ugly, but for now just convert to matrix.to link for compatibility
|
||||
when {
|
||||
// Element custom scheme is not handled by the sdk, convert it to matrix.to link for compatibility
|
||||
deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> {
|
||||
val let = when {
|
||||
deepLink.startsWith(USER_LINK_PREFIX) -> deepLink.substring(USER_LINK_PREFIX.length)
|
||||
deepLink.startsWith(ROOM_LINK_PREFIX) -> deepLink.substring(ROOM_LINK_PREFIX.length)
|
||||
else -> null
|
||||
}?.let {
|
||||
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(it)
|
||||
}?.let { permalinkId ->
|
||||
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(permalinkId)
|
||||
}
|
||||
let
|
||||
}
|
||||
else -> return@let
|
||||
else -> deepLink
|
||||
}
|
||||
|
||||
permalinkHandler.launch(
|
||||
context = this,
|
||||
deepLink = resolvedLink,
|
||||
@ -296,9 +298,11 @@ class HomeActivity :
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { isHandled ->
|
||||
if (!isHandled) {
|
||||
val isMatrixToLink = deepLink.startsWith(PermalinkService.MATRIX_TO_URL_BASE)
|
||||
|| deepLink.startsWith(MATRIX_TO_CUSTOM_SCHEME_URL_BASE)
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.dialog_title_error)
|
||||
.setMessage(R.string.permalink_malformed)
|
||||
.setMessage(if (isMatrixToLink) R.string.permalink_malformed else R.string.universal_link_malformed)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
@ -579,10 +583,6 @@ class HomeActivity :
|
||||
putExtra(MvRx.KEY_ARG, args)
|
||||
}
|
||||
}
|
||||
|
||||
private const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://"
|
||||
private const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/"
|
||||
private const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/"
|
||||
}
|
||||
|
||||
override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState)
|
||||
|
@ -27,6 +27,9 @@ import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import im.vector.app.BuildConfig
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setAttributeBackground
|
||||
import im.vector.app.core.extensions.setAttributeTintedBackground
|
||||
import im.vector.app.core.extensions.setAttributeTintedImageResource
|
||||
import im.vector.app.core.hardware.vibrate
|
||||
import im.vector.app.core.utils.CountUpTimer
|
||||
import im.vector.app.core.utils.DimensionConverter
|
||||
@ -217,7 +220,7 @@ class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Li
|
||||
views.voiceMessageLockArrow.translationY = 0F
|
||||
}
|
||||
RecordingState.LOCKING -> {
|
||||
views.voiceMessageLockImage.setImageResource(R.drawable.ic_voice_message_locked)
|
||||
views.voiceMessageLockImage.setAttributeTintedImageResource(R.drawable.ic_voice_message_locked, R.attr.colorPrimary)
|
||||
val translationAmount = -distanceY.coerceIn(0F, distanceToLock)
|
||||
views.voiceMessageMicButton.translationY = translationAmount
|
||||
views.voiceMessageLockArrow.translationY = translationAmount
|
||||
@ -366,6 +369,7 @@ class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Li
|
||||
|
||||
private fun showRecordingViews() {
|
||||
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic_recording)
|
||||
views.voiceMessageMicButton.setAttributeTintedBackground(R.drawable.circle_with_halo, R.attr.colorPrimary)
|
||||
views.voiceMessageMicButton.updateLayoutParams<MarginLayoutParams> {
|
||||
setMargins(0, 0, 0, 0)
|
||||
}
|
||||
@ -443,6 +447,7 @@ class VoiceMessageRecorderView: ConstraintLayout, VoiceMessagePlaybackTracker.Li
|
||||
private fun resetMicButtonUi() {
|
||||
views.voiceMessageMicButton.isVisible = true
|
||||
views.voiceMessageMicButton.setImageResource(R.drawable.ic_voice_mic)
|
||||
views.voiceMessageMicButton.setAttributeBackground(android.R.attr.selectableItemBackgroundBorderless)
|
||||
views.voiceMessageMicButton.updateLayoutParams<MarginLayoutParams> {
|
||||
if (rtlXMultiplier == -1) {
|
||||
// RTL
|
||||
|
@ -146,7 +146,7 @@ class PreviewUrlRetriever(session: Session,
|
||||
|
||||
companion object {
|
||||
// One week in millis
|
||||
private const val CACHE_VALIDITY: Long = 7 * 24 * 3_600 * 1_000
|
||||
private const val CACHE_VALIDITY = 604_800_000L // 7 * 24 * 3_600 * 1_000
|
||||
|
||||
private val blockedDomains = listOf(
|
||||
"https://matrix.to",
|
||||
|
@ -27,13 +27,12 @@ import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.ActivityProgressBinding
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import im.vector.app.features.login.LoginConfig
|
||||
import im.vector.app.features.permalink.PermalinkHandler
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@ -45,30 +44,38 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
|
||||
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||
@Inject lateinit var permalinkHandler: PermalinkHandler
|
||||
|
||||
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater)
|
||||
|
||||
override fun initUiAndData() {
|
||||
handleIntent()
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntent()
|
||||
}
|
||||
|
||||
private fun handleIntent() {
|
||||
val uri = intent.data
|
||||
|
||||
if (uri == null) {
|
||||
// Should not happen
|
||||
Timber.w("Uri is null")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
if (uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null) {
|
||||
handleConfigUrl(uri)
|
||||
} else if (SUPPORTED_HOSTS.contains(uri.host)) {
|
||||
handleSupportedHostUrl(uri)
|
||||
} else {
|
||||
// Other links are not yet handled, but should not come here (manifest configuration error?)
|
||||
toast(R.string.universal_link_malformed)
|
||||
finish()
|
||||
when {
|
||||
uri == null -> {
|
||||
// Should not happen
|
||||
Timber.w("Uri is null")
|
||||
finish()
|
||||
}
|
||||
uri.getQueryParameter(LoginConfig.CONFIG_HS_PARAMETER) != null -> handleConfigUrl(uri)
|
||||
uri.toString().startsWith(PermalinkService.MATRIX_TO_URL_BASE) -> handleSupportedHostUrl()
|
||||
uri.toString().startsWith(PermalinkHandler.MATRIX_TO_CUSTOM_SCHEME_URL_BASE) -> handleSupportedHostUrl()
|
||||
resources.getStringArray(R.array.permalink_supported_hosts).contains(uri.host) -> handleSupportedHostUrl()
|
||||
else -> {
|
||||
// Other links are not yet handled, but should not come here (manifest configuration error?)
|
||||
toast(R.string.universal_link_malformed)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,53 +88,28 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSupportedHostUrl(uri: Uri) {
|
||||
private fun handleSupportedHostUrl() {
|
||||
// If we are not logged in, open login screen.
|
||||
// In the future, we might want to relaunch the process after login.
|
||||
if (!sessionHolder.hasActiveSession()) {
|
||||
startLoginActivity(uri)
|
||||
finish()
|
||||
} else {
|
||||
convertUriToPermalink(uri)?.let { permalink ->
|
||||
startPermalinkHandler(permalink)
|
||||
} ?: run {
|
||||
// Host is correct but we do not recognize path
|
||||
Timber.w("Unable to handle this uri: $uri")
|
||||
finish()
|
||||
}
|
||||
startLoginActivity()
|
||||
return
|
||||
}
|
||||
|
||||
// We forward intent to HomeActivity (singleTask) to avoid the dueling app problem
|
||||
// https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances
|
||||
intent.setClass(this, HomeActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a URL of element web instance to a matrix.to url
|
||||
* Examples:
|
||||
* - https://riot.im/develop/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
|
||||
* - https://app.element.io/#/room/#element-android:matrix.org -> https://matrix.to/#/#element-android:matrix.org
|
||||
* Start the login screen with identity server and homeserver pre-filled, if any
|
||||
*/
|
||||
private fun convertUriToPermalink(uri: Uri): String? {
|
||||
val uriString = uri.toString()
|
||||
val path = SUPPORTED_PATHS.find { it in uriString } ?: return null
|
||||
return PermalinkService.MATRIX_TO_URL_BASE + uriString.substringAfter(path)
|
||||
}
|
||||
|
||||
private fun startPermalinkHandler(permalink: String) {
|
||||
permalinkHandler.launch(this, permalink, buildTask = true)
|
||||
.delay(500, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { isHandled ->
|
||||
if (!isHandled) {
|
||||
toast(R.string.universal_link_malformed)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the login screen with identity server and homeserver pre-filled
|
||||
*/
|
||||
private fun startLoginActivity(uri: Uri) {
|
||||
private fun startLoginActivity(uri: Uri? = null) {
|
||||
navigator.openLogin(
|
||||
context = this,
|
||||
loginConfig = LoginConfig.parse(uri),
|
||||
loginConfig = uri?.let { LoginConfig.parse(uri) },
|
||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
)
|
||||
finish()
|
||||
@ -173,21 +155,4 @@ class LinkHandlerActivity : VectorBaseActivity<ActivityProgressBinding>() {
|
||||
.setPositiveButton(R.string.ok) { _, _ -> finish() }
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val SUPPORTED_HOSTS = listOf(
|
||||
// Regular Element Web instance
|
||||
"app.element.io",
|
||||
// Other known instances of Element Web
|
||||
"develop.element.io",
|
||||
"staging.element.io",
|
||||
// Previous Web instance, kept for compatibility reason
|
||||
"riot.im"
|
||||
)
|
||||
private val SUPPORTED_PATHS = listOf(
|
||||
"/#/room/",
|
||||
"/#/user/",
|
||||
"/#/group/"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -597,10 +597,12 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
||||
val markRoomReadPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), markRoomReadIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
addAction(NotificationCompat.Action(
|
||||
R.drawable.ic_material_done_all_white,
|
||||
stringProvider.getString(R.string.action_mark_room_read),
|
||||
markRoomReadPendingIntent))
|
||||
NotificationCompat.Action.Builder(R.drawable.ic_material_done_all_white,
|
||||
stringProvider.getString(R.string.action_mark_room_read), markRoomReadPendingIntent)
|
||||
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ)
|
||||
.setShowsUserInterface(false)
|
||||
.build()
|
||||
.let { addAction(it) }
|
||||
|
||||
// Quick reply
|
||||
if (!roomInfo.hasSmartReplyError) {
|
||||
@ -611,6 +613,8 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
||||
NotificationCompat.Action.Builder(R.drawable.vector_notification_quick_reply,
|
||||
stringProvider.getString(R.string.action_quick_reply), replyPendingIntent)
|
||||
.addRemoteInput(remoteInput)
|
||||
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
|
||||
.setShowsUserInterface(false)
|
||||
.build()
|
||||
.let { addAction(it) }
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ 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.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
@ -55,7 +56,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
||||
navigationInterceptor: NavigationInterceptor? = null,
|
||||
buildTask: Boolean = false
|
||||
): Single<Boolean> {
|
||||
if (deepLink == null) {
|
||||
if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) {
|
||||
return Single.just(false)
|
||||
}
|
||||
return Single
|
||||
@ -122,6 +123,13 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
||||
}
|
||||
}
|
||||
|
||||
private fun isPermalinkSupported(context: Context, url: String): Boolean {
|
||||
return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE)
|
||||
|| context.resources.getStringArray(R.array.permalink_supported_hosts).any {
|
||||
url.startsWith(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> {
|
||||
val session = activeSessionHolder.getSafeActiveSession()
|
||||
return if (isRoomAlias && session != null) {
|
||||
@ -179,6 +187,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://"
|
||||
const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/"
|
||||
const val USER_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}user/"
|
||||
}
|
||||
}
|
||||
|
||||
interface NavigationInterceptor {
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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.permalink
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.FragmentProgressBinding
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import im.vector.app.features.home.LoadingFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class PermalinkHandlerActivity : VectorBaseActivity<FragmentProgressBinding>() {
|
||||
|
||||
@Inject lateinit var permalinkHandler: PermalinkHandler
|
||||
@Inject lateinit var sessionHolder: ActiveSessionHolder
|
||||
|
||||
override fun getBinding() = FragmentProgressBinding.inflate(layoutInflater)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_simple)
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.simpleFragmentContainer, LoadingFragment::class.java)
|
||||
}
|
||||
handleIntent()
|
||||
}
|
||||
|
||||
private fun handleIntent() {
|
||||
// If we are not logged in, open login screen.
|
||||
// In the future, we might want to relaunch the process after login.
|
||||
if (!sessionHolder.hasActiveSession()) {
|
||||
startLoginActivity()
|
||||
return
|
||||
}
|
||||
// We forward intent to HomeActivity (singleTask) to avoid the dueling app problem
|
||||
// https://stackoverflow.com/questions/25884954/deep-linking-and-multiple-app-instances
|
||||
intent.setClass(this, HomeActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
startActivity(intent)
|
||||
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
handleIntent()
|
||||
}
|
||||
|
||||
private fun startLoginActivity() {
|
||||
navigator.openLogin(
|
||||
context = this,
|
||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
)
|
||||
finish()
|
||||
}
|
||||
}
|
@ -165,6 +165,12 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
|
||||
}
|
||||
})
|
||||
|
||||
searchView.setOnCloseListener {
|
||||
currentFocus?.clearFocus()
|
||||
searchItem.collapseActionView()
|
||||
true
|
||||
}
|
||||
|
||||
searchView.queryTextChanges()
|
||||
.throttleWithTimeout(600, TimeUnit.MILLISECONDS)
|
||||
.doOnError { err -> Timber.e(err) }
|
||||
@ -174,6 +180,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity<ActivityEmojiReactionPick
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
}
|
||||
searchItem.expandActionView()
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setAttributeTintedImageResource
|
||||
import im.vector.app.core.utils.DebouncedClickListener
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
@ -57,7 +58,7 @@ abstract class SpaceJoinRuleItem : VectorEpoxyModel<SpaceJoinRuleItem.Holder>()
|
||||
holder.upgradeRequiredButton.setOnClickListener(DebouncedClickListener(listener))
|
||||
|
||||
if (selected) {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_on))
|
||||
holder.radioImage.setAttributeTintedImageResource(R.drawable.ic_radio_on, R.attr.colorPrimary)
|
||||
holder.radioImage.contentDescription = holder.view.context.getString(R.string.a11y_checked)
|
||||
} else {
|
||||
holder.radioImage.setImageDrawable(ContextCompat.getDrawable(holder.view.context, R.drawable.ic_radio_off))
|
||||
|
17
vector/src/main/res/drawable/circle_with_halo.xml
Normal file
17
vector/src/main/res/drawable/circle_with_halo.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#33FF0000" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="4dp"
|
||||
android:left="4dp"
|
||||
android:right="4dp"
|
||||
android:top="4dp">
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="#FF0000" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -5,6 +5,6 @@
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,2C6.4771,2 2,6.4771 2,12C2,17.5228 6.4771,22 12,22C17.5228,22 22,17.5228 22,12C22,6.4771 17.5228,2 12,2ZM11.2929,6.2929C11.3888,6.197 11.4993,6.1247 11.6172,6.0759L12.7071,6.2929L12.7075,6.2933L16.7071,10.2929C17.0976,10.6834 17.0976,11.3166 16.7071,11.7071C16.3166,12.0976 15.6834,12.0976 15.2929,11.7071L13,9.4142L13,17C13,17.5523 12.5523,18 12,18C11.4477,18 11,17.5523 11,17L11,9.4142L8.7071,11.7071C8.3166,12.0976 7.6834,12.0976 7.2929,11.7071C6.9024,11.3166 6.9024,10.6834 7.2929,10.2929L11.2929,6.2929ZM11.6172,6.0759L12.705,6.2908C12.5242,6.1111 12.2751,6 12,6C11.8644,6 11.7351,6.027 11.6172,6.0759Z"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillColor="#FF0000"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
@ -9,6 +9,6 @@
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M2,2h20v20h-20z"
|
||||
android:fillColor="#0DBD8B"/>
|
||||
android:fillColor="#FF0000"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="4dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="4"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:pathData="M0,0C2.2091,0 4,1.7909 4,4V28C4,30.2091 2.2091,32 0,32V0Z"
|
||||
android:fillColor="#0DBD8B"/>
|
||||
</vector>
|
@ -1,5 +1,5 @@
|
||||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#0DBD8B" android:fillType="evenOdd" android:pathData="M11.3333,2C8.3878,2 6,4.3878 6,7.3333V10C4.8954,10 4,10.8954 4,12V20C4,21.1046 4.8954,22 6,22H18C19.1046,22 20,21.1046 20,20V12C20,10.8954 19.1046,10 18,10V7.3333C18,4.3878 15.6122,2 12.6667,2H11.3333ZM15.3333,10V7.3333C15.3333,5.8606 14.1394,4.6667 12.6667,4.6667H11.3333C9.8606,4.6667 8.6667,5.8606 8.6667,7.3333V10H15.3333Z"/>
|
||||
<path android:fillColor="#FF0000" android:fillType="evenOdd" android:pathData="M11.3333,2C8.3878,2 6,4.3878 6,7.3333V10C4.8954,10 4,10.8954 4,12V20C4,21.1046 4.8954,22 6,22H18C19.1046,22 20,21.1046 20,20V12C20,10.8954 19.1046,10 18,10V7.3333C18,4.3878 15.6122,2 12.6667,2H11.3333ZM15.3333,10V7.3333C15.3333,5.8606 14.1394,4.6667 12.6667,4.6667H11.3333C9.8606,4.6667 8.6667,5.8606 8.6667,7.3333V10H15.3333Z"/>
|
||||
</vector>
|
||||
|
@ -3,14 +3,6 @@
|
||||
android:height="52dp"
|
||||
android:viewportWidth="52"
|
||||
android:viewportHeight="52">
|
||||
<path
|
||||
android:pathData="M26.173,26.1729m-22.7631,0a22.7631,22.7631 0,1 1,45.5262 0a22.7631,22.7631 0,1 1,-45.5262 0"
|
||||
android:fillColor="#0DBD8B"/>
|
||||
<path
|
||||
android:pathData="M26,26m-26,0a26,26 0,1 1,52 0a26,26 0,1 1,-52 0"
|
||||
android:strokeAlpha="0.2"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillAlpha="0.2"/>
|
||||
<path
|
||||
android:pathData="M21.2414,18.7749C21.2414,16.051 23.4496,13.8429 26.1734,13.8429C28.8973,13.8429 31.1054,16.051 31.1054,18.7749V26.1509C31.1054,28.8747 28.8973,31.0829 26.1734,31.0829C23.4496,31.0829 21.2414,28.8747 21.2414,26.1509V18.7749ZM17.542,24.2475C18.5968,24.2475 19.4518,25.1025 19.4518,26.1572C19.4518,29.8561 22.4509,32.8596 26.1586,32.8675C26.1637,32.8674 26.1689,32.8674 26.174,32.8674C26.179,32.8674 26.184,32.8674 26.189,32.8675C29.896,32.8589 32.8944,29.8556 32.8944,26.1572C32.8944,25.1025 33.7494,24.2475 34.8041,24.2475C35.8588,24.2475 36.7138,25.1025 36.7138,26.1572C36.7138,31.3227 32.9916,35.6165 28.0837,36.5143V37.24C28.0837,38.2947 27.2287,39.1497 26.174,39.1497C25.1193,39.1497 24.2643,38.2947 24.2643,37.24V36.5147C19.3555,35.6176 15.6323,31.3233 15.6323,26.1572C15.6323,25.1025 16.4873,24.2475 17.542,24.2475Z"
|
||||
android:fillColor="#ffffff"
|
||||
|
@ -98,7 +98,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="composerLayout,notificationAreaView,failedMessagesWarningView" />
|
||||
app:constraint_referenced_ids="composerLayout,notificationAreaView,failedMessagesWarningStub" />
|
||||
|
||||
<im.vector.app.features.sync.widget.SyncStateView
|
||||
android:id="@+id/syncStateView"
|
||||
@ -139,6 +139,7 @@
|
||||
android:text="@string/room_jump_to_first_unread"
|
||||
android:visibility="invisible"
|
||||
app:chipIcon="@drawable/ic_jump_to_unread"
|
||||
app:chipIconTint="?colorPrimary"
|
||||
app:closeIcon="@drawable/ic_close_24dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@ -159,7 +160,8 @@
|
||||
android:id="@+id/failedMessagesWarningStub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@layout/view_stub_failed_message_warning_layout"
|
||||
android:inflatedId="@+id/failedMessagesWarningStub"
|
||||
android:layout="@layout/view_stub_failed_message_warning_layout"
|
||||
app:layout_constraintBottom_toTopOf="@id/composerLayout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
@ -24,8 +24,7 @@
|
||||
android:id="@+id/addRoomToSpaceToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:minHeight="0dp"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap|enterAlways">
|
||||
android:minHeight="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -7,5 +7,5 @@
|
||||
app:iconTint="?vctr_content_primary"
|
||||
android:title="@string/search"
|
||||
app:actionViewClass="android.widget.SearchView"
|
||||
app:showAsAction="collapseActionView|ifRoom" />
|
||||
app:showAsAction="collapseActionView|always" />
|
||||
</menu>
|
||||
|
@ -53,11 +53,11 @@
|
||||
<string name="room_displayname_two_members">%1$s وَ %2$s</string>
|
||||
<string name="room_displayname_room_invite">دَعوة غُرفة</string>
|
||||
<plurals name="room_displayname_three_and_more_members">
|
||||
<item quantity="zero"/>
|
||||
<item quantity="zero">لا أحد</item>
|
||||
<item quantity="one">%1$s وواحد آخر</item>
|
||||
<item quantity="two">%1$s و%2$d آخران</item>
|
||||
<item quantity="few">%1$s و%2$d آخرين</item>
|
||||
<item quantity="many">%1$s و%2$d آخرون</item>
|
||||
<item quantity="few">%1$s و%2$d آخرون</item>
|
||||
<item quantity="many">%1$s و%2$d آخرًا</item>
|
||||
<item quantity="other">%1$s و%2$d آخرون</item>
|
||||
</plurals>
|
||||
<string name="summary_you_sent_image">أرسلتَ صورةً.</string>
|
||||
@ -122,17 +122,17 @@
|
||||
<string name="notice_room_server_acl_allow_is_empty">🎉 جميع الخوادِم محظورة مِنَ المُشاركة! لم يعُد من المُمكِن استخدام هذه الغُرفة.</string>
|
||||
<string name="notice_room_server_acl_updated_no_change">لا تغيير.</string>
|
||||
<string name="notice_room_server_acl_updated_ip_literals_not_allowed">• خوادِم مُطابقة IP الحرفية محظورة الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_was_allowed">• الخادِم المُطابق لـ %s قد أُزيل مِن قائمة السماح.</string>
|
||||
<string name="notice_room_server_acl_updated_allowed">• الخادِم المُطابق لـ %s مسموح الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_was_banned">• الخادِم المُطابق لـ %s قد أُزيل مِن قائمة الحظر.</string>
|
||||
<string name="notice_room_server_acl_updated_banned">• الخادِم المُطابق لـ %s محظور الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_was_allowed">• الخوادِم المُطابقة لـ %s أُزيلت مِن قائمة السماح.</string>
|
||||
<string name="notice_room_server_acl_updated_allowed">• الخوادِم المُطابقة لـ %s مسموحة الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_was_banned">• الخوادِم المُطابقة لـ %s أُزيلت مِن قائمة الحظر.</string>
|
||||
<string name="notice_room_server_acl_updated_banned">• الخوادِم المُطابقة لـ %s محظورة الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_ip_literals_allowed">• خوادِم مُطابقة IP الحرفية مسموحة الآن.</string>
|
||||
<string name="notice_room_server_acl_updated_title_by_you">أنتَ قد غيَّرتَ خادِم الـACLs لهذه الغُرفة.</string>
|
||||
<string name="notice_room_server_acl_updated_title">إنَّ %s قد غيَّرَ خادِم الـACLs لهذه الغُرفة.</string>
|
||||
<string name="notice_room_server_acl_set_ip_literals_not_allowed">• الخادِم يحظُر مُطابقة القيم الحرفية للـIP.</string>
|
||||
<string name="notice_room_server_acl_set_allowed">• الخادِم المُطابق لـ %s مسموح.</string>
|
||||
<string name="notice_room_server_acl_set_banned">• الخادِم المُطابق لـ %s محظور.</string>
|
||||
<string name="notice_room_server_acl_set_ip_literals_allowed">• الخادِم يسمح بمُطابقة القيم الحرفية للـIP.</string>
|
||||
<string name="notice_room_server_acl_set_ip_literals_not_allowed">• الخوادِم تحظُر مُطابقة القيم الحرفية للـIP.</string>
|
||||
<string name="notice_room_server_acl_set_allowed">• الخوادِم المُطابقة لـ %s مسموحة.</string>
|
||||
<string name="notice_room_server_acl_set_banned">• الخوادِم المُطابقة لـ %s محظورة.</string>
|
||||
<string name="notice_room_server_acl_set_ip_literals_allowed">• الخوادِم تسمح بمُطابقة القيم الحرفية للـIP.</string>
|
||||
<string name="notice_room_server_acl_set_title_by_you">أنتَ قد عيَّنتَ خادِم الـACLs لهذه الغُرفة.</string>
|
||||
<string name="notice_room_server_acl_set_title">إنَّ %s قد عيَّنَ خادِم الـACLs لهذه الغُرفة.</string>
|
||||
<string name="notice_direct_room_update_by_you">أنتَ قد قمتَ بالترقية هُنا.</string>
|
||||
@ -216,7 +216,7 @@
|
||||
<string name="light_theme">السمة الفاتحة</string>
|
||||
<string name="dark_theme">السمة الداكنة</string>
|
||||
<string name="black_theme">السمة السوداء</string>
|
||||
<string name="notification_sync_in_progress">يُزامن</string>
|
||||
<string name="notification_sync_in_progress">يُزامن…</string>
|
||||
<string name="notification_listening_for_events">يستمع للأحداث</string>
|
||||
<string name="title_activity_home">الرسائل</string>
|
||||
<string name="title_activity_settings">الإعدادات</string>
|
||||
@ -588,7 +588,7 @@
|
||||
<string name="command_error">خطأ في الأمر</string>
|
||||
<string name="unrecognized_command">لم يُفهم الأمر: %s</string>
|
||||
<!-- notification statuses -->
|
||||
<string name="redact">هذّب</string>
|
||||
<string name="redact">أزل</string>
|
||||
<string name="missing_permissions_to_start_conf_call">تحتاج تصريح الدعوة لبدء اجتماع في هذه الغرفة</string>
|
||||
<string name="or">أو</string>
|
||||
<string name="action_quick_reply">ردّ سريع</string>
|
||||
@ -1104,11 +1104,11 @@
|
||||
<string name="room_sliding_menu_version_x">الإصدار %s</string>
|
||||
<string name="settings_notification_advanced">الإعدادات المتقدمة للإشعارات</string>
|
||||
<string name="title_activity_verify_device">توثق من الجهاز</string>
|
||||
<string name="keys_backup_is_not_finished_please_wait">تأمين المفاتيح لم ينته، يرجى الانتظار</string>
|
||||
<string name="keys_backup_is_not_finished_please_wait">النسخ الاحتياطي المفاتيح لم ينته، يرجى الانتظار…</string>
|
||||
<string name="sign_out_bottom_sheet_warning_no_backup">عند تسجيل الخروج الآن ستخسر مفاتيحك</string>
|
||||
<string name="sign_out_bottom_sheet_warning_backing_up">تأمين المفاتيح ما زال جاريا. في حال خروجك الآن لن تتمكن لاحقا من قراءة الرسائل المشفرة</string>
|
||||
<string name="sign_out_bottom_sheet_warning_backup_not_active">تأكد من تفعيل تأمين المفاتيح على كل أجهزتك كي لا تخسر رسائلك المشفرة</string>
|
||||
<string name="sign_out_bottom_sheet_backing_up_keys">يتم تأمين المفاتيح</string>
|
||||
<string name="sign_out_bottom_sheet_warning_backing_up">النسخ الاحتياطي المفاتيح ما زال جاريا. في حال خروجك الآن لن تتمكن لاحقا من قراءة الرسائل المشفرة.</string>
|
||||
<string name="sign_out_bottom_sheet_warning_backup_not_active">تأكد من تفعيل النسخ الاحتياطي للمفاتيح على كل أجهزتك كي لا تخسر رسائلك المشفرة</string>
|
||||
<string name="sign_out_bottom_sheet_backing_up_keys">ينسخ احتياطيا المفاتيح…</string>
|
||||
<string name="no_permissions_to_start_conf_call_in_direct_room">لا يوجد لديك أذن لبدء مكالمة إجتماع</string>
|
||||
<string name="no_permissions_to_start_conf_call">لا يوجد لديك أذن لبدء إجتماع في هذه الغرفة</string>
|
||||
<string name="start_chatting">إبدأ بالمحادثة</string>
|
||||
@ -1123,7 +1123,7 @@
|
||||
<string name="sign_out_bottom_sheet_will_lose_secure_messages">ستفقد الوصول إلى رسائلك المشفرة إلا إذا أخذت نسخة إحتياطية من مفاتيحك قبل تسجيلك للخروج.</string>
|
||||
<string name="backup">نسخة إحتياطية</string>
|
||||
<string name="are_you_sure">هل أنت متأكد؟</string>
|
||||
<string name="keys_backup_activate">إستخدم المفتاح الإحتياطي</string>
|
||||
<string name="keys_backup_activate">إستخدم النسخة الإحتياطية للمفتاح</string>
|
||||
<string name="sign_out_bottom_sheet_dont_want_secure_messages">لا أريد رسائلي المشفرة</string>
|
||||
<string name="title_activity_keys_backup_setup">نسخ إحتياطي للمفتاح</string>
|
||||
<string name="notification_sync_init">جاري إعداد الخدمة</string>
|
||||
@ -1230,4 +1230,26 @@
|
||||
<item quantity="many">أنت أضفت %1$s كعناوين لهذه الغرفة.</item>
|
||||
<item quantity="other">أنت أضفت %1$s كعناوين لهذه الغرفة.</item>
|
||||
</plurals>
|
||||
<string name="denied_permission_generic">لإكمال الاجراء امنح الصلاحيات الناقصة عبر إعدادات النظام.</string>
|
||||
<string name="spaces">الفضاءات</string>
|
||||
<string name="notice_direct_room_guest_access_forbidden_by_you">منعتَ الزوار من دخول الغرفة.</string>
|
||||
<string name="notice_room_guest_access_forbidden">منع %1$s الزوار من دخول الغرفة.</string>
|
||||
<string name="notice_direct_room_guest_access_can_join_by_you">سمحت للزوار بدخول هنا.</string>
|
||||
<string name="notice_direct_room_guest_access_can_join">سمح %1$s للزوار بدخول الغرفة.</string>
|
||||
<string name="notice_room_guest_access_can_join_by_you">سمحتَ للزوار بدخول الغرفة.</string>
|
||||
<string name="notice_room_guest_access_can_join">سمح %1$s للزوار بدخول الغرفة.</string>
|
||||
<string name="notice_room_canonical_alias_no_change_by_you">غيرتَ عناوين الغرفة.</string>
|
||||
<string name="notice_room_canonical_alias_no_change">غّير %1$s عناوين الغرفة.</string>
|
||||
<string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">غيرتَ العناوين الرئيسية والبديلة للغرفة.</string>
|
||||
<string name="notice_room_canonical_alias_alternative_changed_by_you">غيّرت العناوين البديلة للغرفة.</string>
|
||||
<string name="notice_direct_room_guest_access_forbidden">منع %1$s الزوار من دخول الغرفة.</string>
|
||||
<string name="notice_room_guest_access_forbidden_by_you">منعتَ الزوار من دخول الغرفة.</string>
|
||||
<plurals name="notice_room_canonical_alias_alternative_added_by_you">
|
||||
<item quantity="zero">لم تضف أي رابط بديل.</item>
|
||||
<item quantity="one">أضفت الرابط البديل %1$s للغرفة.</item>
|
||||
<item quantity="two">أضفت الرابطين البديلين %1$s للغرفة.</item>
|
||||
<item quantity="few">أضفت الروابط البديلة %1$s للغرفة.</item>
|
||||
<item quantity="many">أضفت الروابط البديلة %1$s للغرفة.</item>
|
||||
<item quantity="other">أضفت الروابط البديلة %1$s للغرفة.</item>
|
||||
</plurals>
|
||||
</resources>
|
@ -2834,8 +2834,8 @@
|
||||
<string name="spaces_feeling_experimental_subspace">Chcete experimentovat\?
|
||||
\nDo Spaceu můžete přidat existující Spaces.</string>
|
||||
<string name="space_add_rooms">Přidat místnosti</string>
|
||||
<string name="space_leave_prompt_msg_as_admin">Jste administrátorem tohoto prostoru, ujistěte se, že jste před odchodem převedli administrátorská práva na jiného člena.</string>
|
||||
<string name="space_leave_prompt_msg_private">Tento prostor není veřejný. Bez pozvánky se do něj nebudete moci znovu připojit.</string>
|
||||
<string name="space_leave_prompt_msg_as_admin">Jste jediným správcem tohoto prostoru. Jeho opuštění bude znamenat, že nad ním nebude mít nikdo kontrolu.</string>
|
||||
<string name="space_leave_prompt_msg_private">Pokud nebudete znovu pozváni, nebudete se moci připojit.</string>
|
||||
<string name="space_leave_prompt_msg_only_you">Jste tu jediný člověk. Pokud odejdete, nikdo se k vám v budoucnu nebude moci připojit, včetně vás.</string>
|
||||
<string name="invite_to_space">Pozvat do %s</string>
|
||||
<string name="a11y_beta">Tato funkce je ve fázi beta</string>
|
||||
@ -3003,4 +3003,49 @@
|
||||
<string name="call_ringing">Vyzvánění…</string>
|
||||
<string name="spaces">Spaces</string>
|
||||
<string name="learn_more">Dozvědět se více</string>
|
||||
<string name="space_add_space_to_any_space_you_manage">Přidejte prostor do jakéhokoli prostoru, který spravujete.</string>
|
||||
<string name="space_add_existing_spaces">Přidat stávající prostory</string>
|
||||
<string name="space_add_existing_rooms_only">Přidat stávající místnosti</string>
|
||||
<string name="pick_tings_to_leave">Vyberte místa, která chcete opustit</string>
|
||||
<string name="leave_specific_ones">Opustit konkrétní místnosti a prostory…</string>
|
||||
<string name="dont_leave_any">Neopouštět žádné místnosti a prostory</string>
|
||||
<string name="you_will_leave_all_in">Opustíte všechny místnosti a prostory v %s.</string>
|
||||
<string name="leave_all_rooms_and_spaces">Opustit všechny místnosti a prostory</string>
|
||||
<string name="space_leave_prompt_msg_with_name">Opravdu chcete opustit %s\?</string>
|
||||
<string name="discovery_section">Objevování (%s)</string>
|
||||
<string name="finish_setup">Dokončit nastavení</string>
|
||||
<string name="discovery_invite">Pozvání e-mailem, vyhledávání kontaktů a další…</string>
|
||||
<string name="finish_setting_up_discovery">Dokončit nastavení objevování.</string>
|
||||
<string name="create_space_identity_server_info_none">V současné době nepoužíváte server identit. Chcete-li pozvat kolegy a být pro ně zjistitelní, nakonfigurujte jej níže.</string>
|
||||
<string name="invite_by_mxid_or_mail">Pozvat pomocí uživatelského jména nebo e-mailu</string>
|
||||
<string name="create_spaces_invite_public_header_desc">Zajistěte, aby měli do společnosti %s přístup ti správní lidé. Další můžete pozvat později.</string>
|
||||
<string name="create_spaces_invite_public_header">Kdo jsou vaši kolegové\?</string>
|
||||
<string name="command_description_add_to_space">Přidat do daného prostoru</string>
|
||||
<string name="create_space_in_progress">Vytváření prostoru…</string>
|
||||
<string name="settings_developer_mode_show_info_on_screen_summary">Zobrazit užitečné informace, které pomohou při ladění aplikace</string>
|
||||
<string name="settings_developer_mode_show_info_on_screen_title">Zobrazení ladících informací na obrazovce</string>
|
||||
<string name="does_not_look_like_valid_email">Nevypadá to jako platná e-mailová adresa</string>
|
||||
<string name="open_discovery_settings">Otevřít nastavení objevování</string>
|
||||
<string name="user_directory_search_hint_2">Vyhledávání podle jména, ID nebo emailu</string>
|
||||
<string name="create_new_space">Vytvořit nový prostor</string>
|
||||
<string name="room_settings_space_access_public_description">Každý může prostor najít a připojit se k němu</string>
|
||||
<string name="room_settings_space_access_title">Adresa prostoru</string>
|
||||
<string name="room_settings_access_rules_pref_dialog_title">Kdo má přístup\?</string>
|
||||
<string name="settings_notification_emails_enable_for_email">Povolit e-mailová oznámení pro %s</string>
|
||||
<string name="settings_notification_emails_no_emails">Pro obdržení e-mailu s upozorněním, přiřaďte e-mail ke svému Matrix účtu</string>
|
||||
<string name="settings_notification_emails_category">Oznámení e-mailem</string>
|
||||
<string name="room_permissions_upgrade_the_space">Povýšit prostor</string>
|
||||
<string name="room_permissions_change_space_name">Změnit název prostoru</string>
|
||||
<string name="room_permissions_enable_space_encryption">Povolit šifrování prostoru</string>
|
||||
<string name="room_permissions_change_space_avatar">Změnit avatar prostoru</string>
|
||||
<string name="room_permissions_change_main_address_for_the_space">Změnit hlavní adresu prostoru</string>
|
||||
<string name="space_permissions_notice_read_only">Nemáte oprávnění k aktualizaci rolí potřebných ke změně různých částí tohoto prostoru</string>
|
||||
<string name="space_permissions_notice">Vyberte role potřebné ke změně různých částí tohoto prostoru</string>
|
||||
<string name="space_settings_permissions_subtitle">Zobrazit a aktualizovat role potřebné ke změně různých částí prostoru.</string>
|
||||
<string name="space_settings_permissions_title">Oprávnění prostoru</string>
|
||||
<string name="space_participants_unban_prompt_msg">Zrušením vykázání uživateli umožní znovu se připojit do prostoru.</string>
|
||||
<string name="space_participants_ban_prompt_msg">Vykázáním uživatele z tohoto prostoru vykopnete a zabráníte mu v dalším připojení.</string>
|
||||
<string name="space_participants_kick_prompt_msg">vykopnutí uživatele je z tohoto prostoru odstraní.
|
||||
\n
|
||||
\nAbyste jim zabránili v dalším vstupu, měli byste je raději vykázat.</string>
|
||||
</resources>
|
@ -2998,4 +2998,36 @@
|
||||
<string name="this_invite_to_this_room_was_sent">Die Einladung zu diesem Raum wurde an %s gesendet, welche nicht mit deinem Konto verknüpft ist</string>
|
||||
<string name="help_space_members">Hilf Space-Mitgliedern private Räume zu finden</string>
|
||||
<string name="settings_mentions_and_keywords_encryption_notice">Auf deinem Mobilgerät wirst du keine Benachrichtigungen für Erwähnungen und Schlüsselwörter in verschlüsselten Räumen erhalten.</string>
|
||||
<string name="space_add_existing_spaces">Existierende Spaces hinzufügen</string>
|
||||
<string name="space_add_existing_rooms_only">Existierende Räume hinzufügen</string>
|
||||
<string name="leave_specific_ones">Ausgewählte Räume oder Spaces verlassen…</string>
|
||||
<string name="dont_leave_any">Keine Räume und Spaces verlassen</string>
|
||||
<string name="you_will_leave_all_in">Du wirst alle Räume und Spaces in %s verlassen.</string>
|
||||
<string name="leave_all_rooms_and_spaces">Alle Räume und Spaces verlassen</string>
|
||||
<string name="space_leave_prompt_msg_with_name">Willst du %s wirklich verlassen\?</string>
|
||||
<string name="invite_by_mxid_or_mail">Mit Benutzername oder E-Mail einladen</string>
|
||||
<string name="command_description_add_to_space">Zum ausgewählten Space hinzufügen</string>
|
||||
<string name="create_space_in_progress">Erstelle Space…</string>
|
||||
<string name="settings_developer_mode_show_info_on_screen_summary">Hilfreiche Informationen zur Fehlersuche anzeigen</string>
|
||||
<string name="settings_developer_mode_show_info_on_screen_title">Debug-Info anzeigen</string>
|
||||
<string name="does_not_look_like_valid_email">Das schaut nicht nach einer gültigen E-Mail-Adresse aus</string>
|
||||
<string name="user_directory_search_hint_2">Nach Name, ID oder E-Mail suchen</string>
|
||||
<string name="create_new_space">Neuen Space erstellen</string>
|
||||
<string name="room_settings_space_access_title">Zugriff</string>
|
||||
<string name="room_settings_access_rules_pref_dialog_title">Wer hat Zugriff\?</string>
|
||||
<string name="settings_notification_emails_enable_for_email">Benachrichtigungen per Email für %s aktivieren</string>
|
||||
<string name="settings_notification_emails_no_emails">Um Benachrichtigungen per E-Mail zu empfangen, musst du einen E-Mail-Adresse hinzufügen</string>
|
||||
<string name="settings_notification_emails_category">Emailbenachrichtigungen</string>
|
||||
<string name="room_permissions_upgrade_the_space">Space upgraden</string>
|
||||
<string name="room_permissions_change_space_name">Namen vom Space ändern</string>
|
||||
<string name="room_permissions_enable_space_encryption">Space verschlüsseln</string>
|
||||
<string name="room_permissions_change_main_address_for_the_space">Hauptadresse vom Space ändern</string>
|
||||
<string name="room_permissions_change_space_avatar">Space-Icon ändern</string>
|
||||
<string name="space_permissions_notice_read_only">Du hast nicht die Berechtigung, Rollenrechte zu bearbeiten</string>
|
||||
<string name="space_settings_permissions_title">Space-Berechtigungen</string>
|
||||
<string name="space_participants_unban_prompt_msg">Wenn du die Person entbannst, kann sie wieder beitreten.</string>
|
||||
<string name="space_participants_ban_prompt_msg">Wenn du eine Person bannst, kann sie nicht erneut beitreten.</string>
|
||||
<string name="space_participants_kick_prompt_msg">Kicken entfernt die Person aus dem Space
|
||||
\n
|
||||
\nUm sie für immer zu entfernen, solltest du sie bannen.</string>
|
||||
</resources>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user