Merge tag 'v1.0.17' into sc

Conflicts:
	vector/build.gradle
	vector/src/main/java/im/vector/app/features/widgets/WidgetArgsBuilder.kt

Note:
Upstream added their own "pass theme to widgets" implementation, which
currently does not respect "black" themes (but treats them as "dark"
themes).
For now, let's integrate our own implementation into the new one.

Change-Id: If99f2f87e20215595fc36996bb530bf5f247b0cb
This commit is contained in:
SpiritCroc 2021-02-10 10:12:00 +01:00
commit 04f4e13230
251 changed files with 6206 additions and 1137 deletions

View File

@ -1,3 +1,25 @@
Changes in Element 1.0.17 (2020-02-09)
===================================================
Improvements 🙌:
- Create a WidgetItemFactory and use it for better rendering of Jitsi widget change (video conference)
- Open image from URL Preview (#2705)
Bugfix 🐛:
- Bug in WidgetContent.computeURL() (#2767)
- Duplicate thumbs | Mobile reactions for 👍 and 👎 are not the same as web (#2776)
- Join room by alias other federation error (#2778)
- HTML unescaping for URL preview (#2766)
- URL preview on reply fallback (#2756)
- RTL: some arrows should be rotated in RTL (#2757)
- Properly delete objects from Realm DB (#2765)
Build 🧱:
- Upgrade build tools
Other changes:
- Change app name from "Element (Riot.im)" to "Element"
Changes in Element 1.0.16 (2020-02-04)
===================================================
@ -24,6 +46,7 @@ Bugfix 🐛:
- Widgets: Support $matrix_widget_id parameter (#2748)
- Data for Worker overload (#2721)
- Fix multiple tasks
- Object deletion in database is not complete (#2759)
SDK API changes ⚠️:
- Increase targetSdkVersion to 30 (#2600)

View File

@ -2,7 +2,7 @@
buildscript {
// Ref: https://kotlinlang.org/releases.html
ext.kotlin_version = '1.4.20'
ext.kotlin_version = '1.4.21'
ext.kotlin_coroutines_version = "1.4.1"
repositories {
google()
@ -12,8 +12,8 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.google.gms:google-services:4.3.5'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.2'

View File

@ -1 +1,2 @@
// TODO
Aquesta nova versió principalment conté correccions d'errors i millores. Ara, enviar un missatge és molt més ràpid.
Registre de canvis complet: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
Aquesta principalment conté millores d'interfície experiència d'usuari. Ara pots convidar amics i crear xats personals ràpidament escanejant codis QR.
Registre de canvis complet: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
Canvis principals d'aquesta versió: previsualització d'URL, nou teclat d'emoticones, noves funcions de configuració de les sales i neu pel Nadal!
Registre de canvis complet: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Canvis principals d'aquesta versió: previsualització d'URL, nou teclat d'emoticones, noves funcions de configuració de les sales i neu pel Nadal!
Registre de canvis complet: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Tato nová verze obsahuje hlavně opravy chyb a vylepšení. Odeslání zprávy je nyní mhohem rychlejší.
Plné znění změn: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
Tato nová verze obsahuje hlavně vylepšení v uživatelském rozhraní. Nyní můžete pozvat přátele a napsat DM velmi rychle skenem QR kódů.
Plné znění změn: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Náhled URL, nová klávesice s Emoji, nové možnosti nastavení místností a sníh na vánoce!
Plné znění změn: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: Náhled URL, nová klávesice s Emoji, nové možnosti nastavení místností a sníh na vánoce!
Plné znění změn: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,30 @@
Element je nový typ aplikace pro výměnu zpráv a kolaboraci, která:
1. Vám dá moc zachovat si soukromí
2. Vás nechá komunikovat s kýmkoli v síti Matrix a dokonce dále integrací s aplikacemi jako Slack
3. Vás ochrání před inzercí, těžbou dat a uzavřenými zahradami
4. Vás zabezpečí šifrováním end-to-end s křížovým podepisováním pro ověření ostatních
Element is completely different from other messaging and collaboration apps because it is decentralised and open source.
Element lets you self-host - or choose a host - so that you have privacy, ownership and control of your data and conversations. It gives you access to an open network; so youre not just stuck speaking to other Element users only. And it is very secure.
Element is able to do all this because it operates on Matrix - the standard for open, decentralised communication.
Element puts you in control by letting you choose who hosts your conversations. From the Element app, you can choose to host in different ways:
1. Get a free account on the matrix.org public server hosted by the Matrix developers, or choose from thousands of public servers hosted by volunteers
2. Self-host your account by running a server on your own hardware
3. Sign up for an account on a custom server by simply subscribing to the Element Matrix Services hosting platform
<b>Why choose Element?</b>
<b>OWN YOUR DATA</b>: You decide where to keep your data and messages. You own it and control it, not some MEGACORP that mines your data or gives access to third parties.
<b>OPEN MESSAGING AND COLLABORATION</b>: You can chat with anyone else in the Matrix network, whether theyre using Element or another Matrix app, and even if they are using a different messaging system of the likes of Slack, IRC or XMPP.
<b>SUPER-SECURE</b>: Real end-to-end encryption (only those in the conversation can decrypt messages), and cross-signing to verify the devices of conversation participants.
<b>COMPLETE COMMUNICATION</b>: Messaging, voice and video calls, file sharing, screen sharing and a whole bunch of integrations, bots and widgets. Build rooms, communities, stay in touch and get things done.
<b>EVERYWHERE YOU ARE</b>: Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://app.element.io.

View File

@ -0,0 +1 @@
Zabezpečený decentralizovaný chat & VoIP. Uchovejte svá data v bezpečí.

View File

@ -0,0 +1 @@
Element (dříve Riot.im)

View File

@ -0,0 +1,2 @@
Hauptänderungen in dieser Version: URL-Vorschau, neue Emoji-Tastatur, neue Raumeinstellungen und Schnee für Weihnachten!
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Hauptänderungen in dieser Version: URL-Vorschau, neue Emoji-Tastatur, neue Raumeinstellungen und Schnee für Weihnachten!
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Main changes in this version: Bug fixes!
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.0.17

View File

@ -0,0 +1,2 @@
Olulisemad muutused selles versioonis: URLide eelvaade, uus klahvistik emojide jaoks, jututubade uued seadistused ja natuke lund jõuludeks!
Muudatuste logi täismahus: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Olulisemad muutused selles versioonis: URLide eelvaade, uus klahvistik emojide jaoks, jututubade uued seadistused ja natuke lund jõuludeks!
Muudatuste logi täismahus: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -1 +1 @@
Element (پیشتر Riot.im)
المنت (ریوت سابق)

View File

@ -0,0 +1,2 @@
Tärkeimmät muutokset tässä versiossa: URL-esikatselu, uusi emoji-näppäimistö, uudet huoneasetukset ja lunta jouluna!
Täysi muutosloki: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Tärkeimmät muutokset tässä versiossa: URL-esikatselu, uusi emoji-näppäimistö, uudet huoneasetukset ja lunta jouluna!
Täysi muutosloki: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Cette nouvelle version contient principalement des améliorations de l'interface utilisateur et de l'expérience utilisateur. Il est désormais possible d'inviter des amis, de créer des DM rapidement et de scanner des codes QR.
Liste complète des changements : https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
Principaux changements apportés par cette version : aperçu des URL, nouveau clavier Emoji, nouvelles options de configuration pour le salon et neige pour Noël.
Liste complète des changements : https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Principaux changements apportés par cette version : aperçu des URL, nouveau clavier Emoji, nouvelles options de configuration pour le salon et neige pour Noël.
Liste complète des changements : https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
גרסה חדשה זו מכילה בעיקר תיקוני באגים ושיפורים. שליחת הודעה עכשיו הרבה יותר מהירה.
לוח שינויים מלא: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
גרסה חדשה זו מכילה בעיקר שיפורים בממשק המשתמש וחוויית המשתמש. עכשיו אתה יכול להזמין חברים וליצור DM מהר מאוד על ידי סריקת קודי QR.
לוח שינויים מלא: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
שינויים עיקריים בגרסה זו: תצוגה מקדימה של כתובת URL, מקלדת Emoji חדשה, יכולות הגדרת חדרים חדשות ושלג לחג המולד!
לוח שינויים מלא: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
שינויים עיקריים בגרסה זו: תצוגה מקדימה של כתובת URL, מקלדת Emoji חדשה, יכולות הגדרת חדרים חדשות ושלג לחג המולד!
לוח שינויים מלא: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,30 @@
אלמנט הוא סוג חדש של אפליקציית מסנג'רים ושיתופי פעולה ש:
1. נותן לך שליטה לשמור על פרטיותך
2. מאפשר לך לתקשר עם כל אחד ברשת מטריקס, ואף מעבר לכך על ידי שילוב עם אפליקציות כגון Slack
3. מגן עליכם מפני פרסום, ייצור נתונים וגינות חומות
4. מאבטח אותך באמצעות הצפנה מקצה לקצה, באמצעות חתימה צולבת כדי לאמת אחרים
אלמנט שונה לחלוטין מאפליקציות העברת הודעות ושיתופי פעולה מכיוון שהוא מבוזר ומקור פתוח.
אלמנט מאפשר לך לארח בעצמך - או לבחור מארח - כך שתהיה לך פרטיות, בעלות ושליטה בנתונים ובשיחות שלך. זה נותן לך גישה לרשת פתוחה; כך שאתה לא סתם תקוע לדבר עם משתמשי Element אחרים בלבד. וזה מאוד מאובטח.
אלמנט מסוגל לעשות את כל זה מכיוון שהוא פועל במטריקס - הסטנדרט לתקשורת פתוחה ומבוזרת.
אלמנט מכניס אותך לשליטה בכך שהוא מאפשר לבחור מי מארח את השיחות שלך. מאפליקציית Element תוכלו לבחור לארח בדרכים שונות:
1. קבל חשבון חינם בשרת הציבורי matrix.org המתארח על ידי מפתחי מטריקס, או בחר מתוך אלפי שרתים ציבוריים המתארחים על ידי מתנדבים.
2. אירח את חשבונך באופן עצמאי על ידי הפעלת שרת בחומרה משלך
3. הירשם לחשבון בשרת מותאם אישית על ידי מנוי פשוט לפלטפורמת האירוח של מטריקס מטריקס
<b> מדוע לבחור באלמנט? </b>
<b> בבעלות הנתונים שלך </b>: אתה מחליט היכן לשמור את הנתונים וההודעות שלך. אתה הבעלים שלה ושולט בו, לא על איזה MEGACORP שמכרה את הנתונים שלך או נותן גישה לצדדים שלישיים.
<b> הודעות ושיתוף פעולה פתוח </b>: אתה יכול לשוחח בצ'אט עם כל אחד אחר ברשת מטריקס, בין אם הוא משתמש באלמנט או באפליקציית מטריקס אחרת, וגם אם הם משתמשים במערכת העברת הודעות אחרת כמו Slack, IRC או XMPP.
<b> SUPER-SECURE </b>: הצפנה אמיתית מקצה לקצה (רק מי שבשיחה יכול לפענח הודעות), וחתימה צולבת כדי לאמת את המכשירים של משתתפי השיחה.
<b> תקשורת מלאה </b>: הודעות, שיחות קול ווידאו, שיתוף קבצים, שיתוף מסך וחבורה שלמה של אינטגרציות, בוטים ווידג'טים. לבנות חדרים, קהילות, לשמור על קשר ולעשות דברים.
<b> בכל מקום שאתה נמצא </b>: הישאר בקשר בכל מקום שאתה נמצא עם היסטוריית הודעות מסונכרנת לחלוטין בכל המכשירים שלך באינטרנט בכתובת https://app.element.io.

View File

@ -0,0 +1 @@
צ'ט מבוזר ומאובטח. שמור על המידע שלך מפני צדדים שלישיים.

View File

@ -0,0 +1 @@
אלמנט (בעבר Riot.im)

View File

@ -0,0 +1,2 @@
Főbb változtatások ebben a verzióban: URL előnézet, új emoji billentyűzet, új szoba beállítási lehetőségek, és hó karácsonyra!
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Főbb változtatások ebben a verzióban: URL előnézet, új emoji billentyűzet, új szoba beállitási lehetőségek, és hó karácsonyra!
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Modifiche principali in questa versione: anteprima URL, nuova tastiera emoji, nuove impostazioni stanza e neve per Natale!
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Modifiche principali in questa versione: anteprima URL, nuova tastiera emoji, nuove impostazioni stanza e neve per Natale!
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Principais mudanças nessa versão: Prévia do endereço URL, novo teclado de Emojis, novos recursos de configuração da sala, e neve para o Natal!
Registro de alterações completo: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Principais mudanças nessa versão: Prévia do endereço URL, novo teclado de Emojis, novos recursos de configuração da sala, e neve para o Natal!
Registro de alterações completo: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Основные изменения в этой версии: предварительный просмотр URL, новая клавиатура эмодзи, новые возможности настройки комнаты и снег на Рождество!
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Основные изменения в этой версии: предварительный просмотр URL, новая клавиатура эмодзи, новые возможности настройки комнаты и снег на Рождество!
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Ова нова верзија углавном садржи поправке грешака и побољшања. Слање порука сада је много брже.
Дневник свих измена: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
Ова нова верзија углавном садржи побољшања корисничког искуства и сучеља. Сада можете позвати пријатеље и направити ћаскања веома брзо скенирањем КуЕр кодова.
Дневник свих измена: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
Главне измене у овој верзији: УРЛ преглед, нова емоџи тастатура, нове могућности у поставкама собе и снег за Божић !
Дневник свих измена: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Главне измене у овој верзији: УРЛ преглед, нова емоџи тастатура, нове могућности у поставкама собе и снег за Божић !
Дневник свих измена: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,30 @@
Елемент је нова врста апликације за ћаскање и сарадњу која:
1. вама даје контролу над вашом приватношћу
2. омогућава комуникацију са свима на Матрикс (Matrix) мрежи, па и шире интегришући се са апликацијама попут Слека (Slack)
3. вас штити од рекламирања, крађе података и затворених система
4. вас обезбеђује шифровањем с краја на крај, са међу-потписима ради верификовања осталих корисника
Елемент је потпуно другачији од осталих апликација за поруке и сарадњу јер је децентрализован и отвореног кода.
Елемент омогућава да сами хостујете или изаберете хост - како бисте сачували приватност, власништво и контролу над својим подацима и разговорима. Даје вам приступ отвореној мрежи; па тако нисте ограничени да причате само са осталим Елемент корисницима. И наравно веома је безбедан.
Елемент је способан да понуди све ово јер је базиран на Матриксу — што је стандард за отворену, децентрализовану комуникацију.
Елемент омогућава да контролишете ко ће бити домаћин ваших конверзација. Из Елемент апликације, домаћина можете изабрати на више начина:
1. Узмите бесплатан налог на matrix.org јавном серверу који хостују Матрикс програмериили изаберите неки од хиљада јавних сервера који хостују волонтери
2. Сами хостујте свој налог покрећући сервер на свом сопственом хардверу
3. Пријавите се за налог на посебним серверима једноставно прретплативши се на „Елементову Матрикс сервис“ хостинг платформу
<b>Зашто изабрати Елемент?</b>
<b>ПОСЕДУЈТЕ СВОЈЕ ПОДАТКЕ</b>: Ви одлучујете где ћете чувати своје податке и поруке. Ви их поседујете и контролишете, не нека МЕГАКОРПОРАЦИЈА која бунари по вашим подацима или омогућава приступ трећим странама.
<b>ОТВОРЕНА КОМУНИКАЦИЈА И САРАДЊА</b>: Можете ћаскати са свима на Матрикс мрежи, без обзира да ли користе Елемент или другу Матрикс апликацију, па чак иако користе другачији систем порука, попут Слека (Slack), ИРЦ-а (IRC) или ИксМПП (XMPP).
<b>СУПЕР-БЕЗБЕДАН</b>: Право с-краја-на-крај шифровање (само они који су у разговору могу да дешифрују поруке), и међу-потписивање ради верификације уређаја учесника у конверзацији.
<b>КОМПЛЕТНА КОМУНИКАЦИЈА</b>: Поруке, гласовни и видео позиви, дељење фајлова и екрана и гомила интеграција, ботова и виџета. Правите собе, заједнице, останите у контакту и завршавајте послове.
<b>СВУДА ГДЕ СТЕ ВИ</b>: Останите у контакту без обзира где сте, са потпуно синхронизованом историјом порука на свим вашим уређајима па и на вебу на https://app.element.io.

View File

@ -0,0 +1 @@
Сигурно децентрализовано ћаскање и разговори. Држите своје податке безбедним.

View File

@ -0,0 +1 @@
Елемент (претходно Riot.im)

View File

@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: URL-förhandsgranskning, bytt emojitangentbord, nya rumsinställningsförmågor, och en vit jul!
Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: URL-förhandsgranskning, nya rumsinställningsförmågor, och en vit jul!
Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Bu yeni sürüm başlıca hata düzeltmeleri ve iyileştirmeler içerir. Mesaj göndermek artık çok daha hızlı.
Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
Bu yeni sürüm, temel olarak kullanıcı arayüzü ve kullanıcı deneyimi iyileştirmelerini içerir. Artık QR kodlarını tarayarak arkadaşlarınızı davet edebilir ve çok hızlı bir şekilde DM oluşturabilirsiniz.
Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -0,0 +1,2 @@
Bu sürümdeki başlıca değişiklikler: URL ön izlemesi , yeni Emoji klavyesi, yeni oda ayarları ve Yılbaşı için kar!
Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Bu sürümdeki başlıca değişiklikler: URL ön izlemesi , yeni Emoji klavyesi, yeni oda ayarları ve Yılbaşı için kar!
Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,30 @@
Element, şu özelliklere sahip yeni bir tür mesajlaşma ve işbirliği uygulamasıdır:
1. Gizliliğinizi korumak için kontrolü size verir
2. Matrix ağındaki herkesle ve hatta Slack gibi uygulamalarla entegre olarak iletişim kurmanızı sağlar
3. Sizi reklamlardan, veri madenciliğinden ve walled gardenlardan korur
4. Başkalarını doğrulamak için çapraz imzalama ile uçtan uca şifreleme yoluyla güvenliğinizi sağlar
Element, dağıtık (decentralized) ve açık kaynak olduğu için diğer mesajlaşma ve işbirliği uygulamalarından tamamen farklıdır.
Element kendi sunucunuzu kurmanıza yada bir sunucu seçmenizi izin verir, böylece verilerinizin ve sohbetlerinizin gizliliğine ve kontrolüne sahip olursunuz. Size açık bir ağa erişim sağlar; yani yalnızca diğer Element kullanıcılarıyla konuşmak zorunda kalmazsınız. Ve çok güvenlidir.
Element, açık, merkezi olmayan iletişim standardı olan Matrix üzerinde çalıştığı için tüm bunları yapabilir.
Element, konuşmalarınızın sunucusunu seçmenize izin vererek kontrolü size verir. Element uygulamasından, farklı şekillerde sunucu seçebilirsiniz:
1. Matrix geliştiricilerinin sahip olduğu matrix.org genel sunucusunda ücretsiz bir hesap edinin veya gönüllüler tarafından barındırılan binlerce genel sunucu arasından seçim yapın
2. Kendi donanımınız üzerinde bir sunucu çalıştırarak kendi hesabınızı barındırın
3. Element Matrix Hizmetleri sunucu platformuna abone olarak özel bir sunucuda hesap oluşturun
<b>Neden Element'i Seçmelisiniz</b>
<b>KENDİ VERİLERİNİZE SAHİP OLUN </b>: Verilerinizi ve mesajlarınızı nerede saklayacağınıza siz karar verirsiniz. Verilerinize madencilik yapan veya üçüncü şahıslara erişim sağlayan bir BÜYÜKŞİRKETE verilerinizi vermiyorsunuz, onlara sahipsiniz ve kontrol ediyorsunuz.
<b>AÇIK MESAJLAŞMA VE İŞBİRLİĞİ</b>: Element veya başka bir Matrix uygulamalarını kullanmaları fark etmeksizin, hatta Slack, IRC yada XMPP gibi farklı mesajlaşma uygulamaları kullanıyor olsalar bile, Matrix sunucusundaki herhangi biriyle konuşabilirsiniz
<b>SÜPER GÜVENLİ</b>: Gerçek uçtan uca şifreleme (yalnızca görüştüğünüz kişiler mesajların şifresini çözebilir) ve konuşma katılımcılarının cihazlarını doğrulamak için çapraz imzalama.
<b>TAM İLETİŞİM</b>: Mesajlaşma, sesli ve görüntülü aramalar, dosya paylaşımı, ekran paylaşımı ve bir sürü entegrasyon, bot ve widgetlar. Odalar, topluluklar oluşturun, iletişimde kalın ve işlerinizi halledin.
<b>OLDUĞUNUZ HER YERDE</b>: Nerede olursanız olun, tüm cihazlarınızda ve internette https://app.element.io adresinden tam senkronize mesaj geçmişiyle iletişimde kalın

View File

@ -0,0 +1,2 @@
Основні зміни в цій версії: попередній перегляд URL-адреси, нова клавіатура Emoji, нові можливості налаштування кімнати та сніг на Різдво!
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
Основні зміни в цій версії: попередній перегляд URL-адреси, нова клавіатура Emoji, нові можливості налаштування кімнати та сніг на Різдво!
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@ -0,0 +1,2 @@
此新版本主要包含错误修复和改进。现在,发送消息要快得多。
完整更新日志https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@ -0,0 +1,2 @@
此新版本主要包含用户界面和用户体验方面的改进。现在,您可以邀请朋友,并通过扫描二维码快速创建私聊。
完整更新日志https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=3db89524a3981819ff28c3f979236c1274a726e146ced0c8a2020417f9bc0782
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip
distributionSha256Sum=1433372d903ffba27496f8d5af24265310d2da0d78bf6b4e5138831d4fe066e9
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.room.sender
import org.matrix.android.sdk.internal.util.replaceSpaceChars
data class SenderInfo(
val userId: String,
/**
@ -27,8 +29,9 @@ data class SenderInfo(
) {
val disambiguatedDisplayName: String
get() = when {
displayName.isNullOrBlank() -> userId
isUniqueDisplayName -> displayName
else -> "$displayName ($userId)"
displayName == null -> userId
displayName.replaceSpaceChars().isBlank() -> "$displayName ($userId)"
isUniqueDisplayName -> displayName
else -> "$displayName ($userId)"
}
}

View File

@ -97,10 +97,11 @@ interface WidgetService {
): LiveData<List<Widget>>
/**
* Creates a new widget in a room. It makes sure you have the rights to handle this.
* Creates and send a new widget in a room. It makes sure you have the rights to handle this.
*
* @param roomId: the room where you want to deactivate the widget.
* @param widgetId: the widget to deactivate.
* @param roomId the room where you want to create the widget.
* @param widgetId the widget to create.
* @param content the content of the widget
* @param callback the matrix callback to listen for result.
* @return Cancelable
*/

View File

@ -20,7 +20,7 @@ object ContentUtils {
val lines = repliedBody.lines()
var wellFormed = repliedBody.startsWith(">")
var endOfPreviousFound = false
val usefullines = ArrayList<String>()
val usefulLines = ArrayList<String>()
lines.forEach {
if (it == "") {
endOfPreviousFound = true
@ -29,10 +29,10 @@ object ContentUtils {
if (!endOfPreviousFound) {
wellFormed = wellFormed && it.startsWith(">")
} else {
usefullines.add(it)
usefulLines.add(it)
}
}
return usefullines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
return usefulLines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
}
fun extractUsefulTextFromHtmlReply(repliedBody: String): String {

View File

@ -35,3 +35,10 @@ fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder
return this
}
fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
params.forEach { (param, value) ->
appendParamToUrl(param, value)
}
return this
}

View File

@ -21,11 +21,11 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
import timber.log.Timber
fun CryptoDeviceInfo.canonicalSignable(): String {
internal fun CryptoDeviceInfo.canonicalSignable(): String {
return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
}
fun CryptoCrossSigningKey.canonicalSignable(): String {
internal fun CryptoCrossSigningKey.canonicalSignable(): String {
return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary())
}
@ -40,7 +40,7 @@ fun String.fromBase64(): ByteArray {
/**
* Decode the base 64. Return null in case of bad format. Should be used when parsing received data from external source
*/
fun String.fromBase64Safe(): ByteArray? {
internal fun String.fromBase64Safe(): ByteArray? {
return try {
Base64.decode(this, Base64.DEFAULT)
} catch (throwable: Throwable) {

View File

@ -63,7 +63,7 @@ data class CryptoCrossSigningKey(
)
}
data class Builder(
internal data class Builder(
val userId: String,
val usage: KeyUsage,
private var base64Pkey: String? = null,
@ -97,7 +97,7 @@ data class CryptoCrossSigningKey(
}
}
enum class KeyUsage(val value: String) {
internal enum class KeyUsage(val value: String) {
MASTER("master"),
SELF_SIGNING("self_signing"),
USER_SIGNING("user_signing")

View File

@ -83,6 +83,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity
import org.matrix.android.sdk.internal.crypto.store.db.model.createPrimaryKey
import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade
import org.matrix.android.sdk.internal.crypto.store.db.query.create
import org.matrix.android.sdk.internal.crypto.store.db.query.delete
import org.matrix.android.sdk.internal.crypto.store.db.query.get
@ -94,6 +95,7 @@ import org.matrix.android.sdk.internal.di.CryptoDatabase
import org.matrix.android.sdk.internal.di.DeviceId
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.extensions.clearWith
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.olm.OlmAccount
import org.matrix.olm.OlmException
@ -293,7 +295,7 @@ internal class RealmCryptoStore @Inject constructor(
realm.insertOrUpdate(entity)
}
// Ensure all other devices are deleted
u.devices.deleteAllFromRealm()
u.devices.clearWith { it.deleteOnCascade() }
u.devices.addAll(new)
}
}
@ -309,7 +311,7 @@ internal class RealmCryptoStore @Inject constructor(
.let { userEntity ->
if (masterKey == null || selfSigningKey == null) {
// The user has disabled cross signing?
userEntity.crossSigningInfoEntity?.deleteFromRealm()
userEntity.crossSigningInfoEntity?.deleteOnCascade()
userEntity.crossSigningInfoEntity = null
} else {
var shouldResetMyDevicesLocalTrust = false
@ -1633,7 +1635,7 @@ internal class RealmCryptoStore @Inject constructor(
} else {
// Just override existing, caller should check and untrust id needed
val existing = CrossSigningInfoEntity.getOrCreate(realm, userId)
existing.crossSigningKeys.deleteAllFromRealm()
existing.crossSigningKeys.clearWith { it.deleteOnCascade() }
existing.crossSigningKeys.addAll(
info.crossSigningKeys.map {
crossSigningKeysMapper.map(it)

View File

@ -16,10 +16,11 @@
package org.matrix.android.sdk.internal.crypto.store.db.model
import org.matrix.android.sdk.internal.crypto.model.KeyUsage
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import org.matrix.android.sdk.internal.crypto.model.KeyUsage
import org.matrix.android.sdk.internal.extensions.clearWith
internal open class CrossSigningInfoEntity(
@PrimaryKey
@ -56,3 +57,8 @@ internal open class CrossSigningInfoEntity(
info?.let { crossSigningKeys.add(it) }
}
}
internal fun CrossSigningInfoEntity.deleteOnCascade() {
crossSigningKeys.clearWith { it.deleteOnCascade() }
deleteFromRealm()
}

View File

@ -47,3 +47,8 @@ internal open class DeviceInfoEntity(
companion object
}
internal fun DeviceInfoEntity.deleteOnCascade() {
trustLevelEntity?.deleteFromRealm()
deleteFromRealm()
}

View File

@ -30,3 +30,8 @@ internal open class KeyInfoEntity(
var signatures: String? = null,
var trustLevelEntity: TrustLevelEntity? = null
) : RealmObject()
internal fun KeyInfoEntity.deleteOnCascade() {
trustLevelEntity?.deleteFromRealm()
deleteFromRealm()
}

View File

@ -19,13 +19,20 @@ package org.matrix.android.sdk.internal.crypto.store.db.model
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import org.matrix.android.sdk.internal.extensions.clearWith
internal open class UserEntity(
@PrimaryKey var userId: String? = null,
var devices: RealmList<DeviceInfoEntity> = RealmList(),
var crossSigningInfoEntity: CrossSigningInfoEntity? = null,
var deviceTrackingStatus: Int = 0)
: RealmObject() {
var deviceTrackingStatus: Int = 0
) : RealmObject() {
companion object
}
internal fun UserEntity.deleteOnCascade() {
devices.clearWith { it.deleteOnCascade() }
crossSigningInfoEntity?.deleteOnCascade()
deleteFromRealm()
}

View File

@ -16,11 +16,12 @@
package org.matrix.android.sdk.internal.crypto.store.db.query
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
import io.realm.Realm
import io.realm.kotlin.createObject
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.deleteOnCascade
/**
* Get or create a user
@ -39,5 +40,5 @@ internal fun UserEntity.Companion.delete(realm: Realm, userId: String) {
realm.where<UserEntity>()
.equalTo(UserEntityFields.USER_ID, userId)
.findFirst()
?.deleteFromRealm()
?.deleteOnCascade()
}

View File

@ -21,7 +21,7 @@ import org.matrix.olm.OlmPkEncryption
import org.matrix.olm.OlmPkSigning
import org.matrix.olm.OlmUtility
fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
internal fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
val olmPkEncryption = OlmPkEncryption()
try {
return block(olmPkEncryption)
@ -30,7 +30,7 @@ fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
}
}
fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
internal fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
val olmPkDecryption = OlmPkDecryption()
try {
return block(olmPkDecryption)
@ -39,7 +39,7 @@ fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
}
}
fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
internal fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
val olmPkSigning = OlmPkSigning()
try {
return block(olmPkSigning)
@ -48,7 +48,7 @@ fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
}
}
fun <T> withOlmUtility(block: (OlmUtility) -> T): T {
internal fun <T> withOlmUtility(block: (OlmUtility) -> T): T {
val olmUtility = OlmUtility()
try {
return block(olmUtility)

View File

@ -16,6 +16,10 @@
package org.matrix.android.sdk.internal.database
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.matrix.android.sdk.internal.database.helper.nextDisplayIndex
import org.matrix.android.sdk.internal.database.model.ChunkEntity
import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
@ -23,14 +27,11 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
import org.matrix.android.sdk.internal.task.TaskExecutor
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ -56,7 +57,7 @@ internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val
}
}
private suspend fun cleanUp(realm: Realm, threshold: Long) {
private fun cleanUp(realm: Realm, threshold: Long) {
val numberOfEvents = realm.where(EventEntity::class.java).findAll().size
val numberOfTimelineEvents = realm.where(TimelineEventEntity::class.java).findAll().size
Timber.v("Number of events in db: $numberOfEvents | Number of timeline events in db: $numberOfTimelineEvents")
@ -76,20 +77,7 @@ internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val
chunk.numberOfTimelineEvents = chunk.numberOfTimelineEvents - eventsToRemove.size
eventsToRemove.forEach {
val canDeleteRoot = it.root?.stateKey == null
if (canDeleteRoot) {
it.root?.deleteFromRealm()
}
it.readReceipts?.readReceipts?.deleteAllFromRealm()
it.readReceipts?.deleteFromRealm()
it.annotations?.apply {
editSummary?.deleteFromRealm()
pollResponseSummary?.deleteFromRealm()
referencesSummaryEntity?.deleteFromRealm()
reactionsSummary.deleteAllFromRealm()
}
it.annotations?.deleteFromRealm()
it.readReceipts?.deleteFromRealm()
it.deleteFromRealm()
it.deleteOnCascade(canDeleteRoot)
}
// We reset the prevToken so we will need to fetch again.
chunk.prevToken = null

View File

@ -38,12 +38,6 @@ import io.realm.Sort
import io.realm.kotlin.createObject
import timber.log.Timber
internal fun ChunkEntity.deleteOnCascade() {
assertIsManaged()
this.timelineEvents.deleteAllFromRealm()
this.deleteFromRealm()
}
internal fun ChunkEntity.merge(roomId: String, chunkToMerge: ChunkEntity, direction: PaginationDirection) {
assertIsManaged()
val localRealm = this.realm

View File

@ -19,12 +19,7 @@ package org.matrix.android.sdk.internal.database.helper
import org.matrix.android.sdk.internal.database.model.ChunkEntity
import org.matrix.android.sdk.internal.database.model.RoomEntity
internal fun RoomEntity.deleteOnCascade(chunkEntity: ChunkEntity) {
chunks.remove(chunkEntity)
chunkEntity.deleteOnCascade()
}
internal fun RoomEntity.addOrUpdate(chunkEntity: ChunkEntity) {
internal fun RoomEntity.addIfNecessary(chunkEntity: ChunkEntity) {
if (!chunks.contains(chunkEntity)) {
chunks.add(chunkEntity)
}

View File

@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.database.helper
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.extensions.assertIsManaged
import io.realm.Realm
internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long {
@ -29,11 +28,3 @@ internal fun TimelineEventEntity.Companion.nextId(realm: Realm): Long {
currentIdNum.toLong() + 1
}
}
internal fun TimelineEventEntity.deleteOnCascade() {
assertIsManaged()
root?.deleteFromRealm()
annotations?.deleteFromRealm()
readReceipts?.deleteFromRealm()
deleteFromRealm()
}

View File

@ -21,6 +21,8 @@ import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.Index
import io.realm.annotations.LinkingObjects
import org.matrix.android.sdk.internal.extensions.assertIsManaged
import org.matrix.android.sdk.internal.extensions.clearWith
internal open class ChunkEntity(@Index var prevToken: String? = null,
// Because of gaps we can have several chunks with nextToken == null
@ -43,3 +45,12 @@ internal open class ChunkEntity(@Index var prevToken: String? = null,
companion object
}
internal fun ChunkEntity.deleteOnCascade(deleteStateEvents: Boolean, canDeleteRoot: Boolean) {
assertIsManaged()
if (deleteStateEvents) {
stateEvents.deleteAllFromRealm()
}
timelineEvents.clearWith { it.deleteOnCascade(canDeleteRoot) }
deleteFromRealm()
}

View File

@ -31,3 +31,11 @@ internal open class EventAnnotationsSummaryEntity(
companion object
}
internal fun EventAnnotationsSummaryEntity.deleteOnCascade() {
reactionsSummary.deleteAllFromRealm()
editSummary?.deleteFromRealm()
referencesSummaryEntity?.deleteFromRealm()
pollResponseSummary?.deleteFromRealm()
deleteFromRealm()
}

View File

@ -40,3 +40,8 @@ internal open class PushRuleEntity(
companion object
}
internal fun PushRuleEntity.deleteOnCascade() {
conditions?.deleteAllFromRealm()
deleteFromRealm()
}

View File

@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.model
import org.matrix.android.sdk.api.pushrules.RuleKind
import io.realm.RealmList
import io.realm.RealmObject
import org.matrix.android.sdk.internal.extensions.clearWith
internal open class PushRulesEntity(
var scope: String = "",
@ -35,3 +36,8 @@ internal open class PushRulesEntity(
companion object
}
internal fun PushRulesEntity.deleteOnCascade() {
pushRules.clearWith { it.deleteOnCascade() }
deleteFromRealm()
}

View File

@ -15,8 +15,8 @@
*/
package org.matrix.android.sdk.internal.database.model
import org.matrix.android.sdk.api.session.pushers.PusherState
import io.realm.RealmObject
import org.matrix.android.sdk.api.session.pushers.PusherState
// TODO
// at java.lang.Thread.run(Thread.java:764)
@ -54,3 +54,8 @@ internal open class PusherEntity(
companion object
}
internal fun PusherEntity.deleteOnCascade() {
data?.deleteFromRealm()
deleteFromRealm()
}

View File

@ -34,3 +34,8 @@ internal open class ReadReceiptsSummaryEntity(
companion object
}
internal fun ReadReceiptsSummaryEntity.deleteOnCascade() {
readReceipts.deleteAllFromRealm()
deleteFromRealm()
}

View File

@ -20,6 +20,7 @@ import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.Index
import io.realm.annotations.LinkingObjects
import org.matrix.android.sdk.internal.extensions.assertIsManaged
internal open class TimelineEventEntity(var localId: Long = 0,
@Index var eventId: String = "",
@ -39,3 +40,13 @@ internal open class TimelineEventEntity(var localId: Long = 0,
companion object
}
internal fun TimelineEventEntity.deleteOnCascade(canDeleteRoot: Boolean) {
assertIsManaged()
if (canDeleteRoot) {
root?.deleteFromRealm()
}
annotations?.deleteOnCascade()
readReceipts?.deleteOnCascade()
deleteFromRealm()
}

View File

@ -16,8 +16,18 @@
package org.matrix.android.sdk.internal.extensions
import io.realm.RealmList
import io.realm.RealmObject
internal fun RealmObject.assertIsManaged() {
check(isManaged) { "${javaClass.simpleName} entity should be managed to use this function" }
}
/**
* Clear a RealmList by deleting all its items calling the provided lambda
*/
internal fun <T> RealmList<T>.clearWith(delete: (T) -> Unit) {
while (!isEmpty()) {
first()?.let { delete.invoke(it) }
}
}

View File

@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import org.matrix.android.sdk.internal.util.awaitTransaction
import org.matrix.android.sdk.internal.util.unescapeHtml
import java.util.Date
import javax.inject.Inject
@ -73,9 +74,9 @@ internal class DefaultGetPreviewUrlTask @Inject constructor(
private fun JsonDict.toPreviewUrlData(url: String): PreviewUrlData {
return PreviewUrlData(
url = (get("og:url") as? String) ?: url,
siteName = get("og:site_name") as? String,
title = get("og:title") as? String,
description = get("og:description") as? String,
siteName = (get("og:site_name") as? String)?.unescapeHtml(),
title = (get("og:title") as? String)?.unescapeHtml(),
description = (get("og:description") as? String)?.unescapeHtml(),
mxcUrl = get("og:image") as? String
)
}

View File

@ -21,6 +21,8 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
import org.matrix.android.sdk.api.session.room.timeline.isReply
import org.matrix.android.sdk.api.util.ContentUtils
import javax.inject.Inject
internal class UrlsExtractor @Inject constructor() {
@ -35,7 +37,14 @@ internal class UrlsExtractor @Inject constructor() {
|| it.msgType == MessageType.MSGTYPE_NOTICE
|| it.msgType == MessageType.MSGTYPE_EMOTE
}
?.body
?.let { messageContent ->
if (event.isReply()) {
// This is a reply, strip the reply fallback
ContentUtils.extractUsefulTextFromReply(messageContent.body)
} else {
messageContent.body
}
}
?.let { urlRegex.findAll(it) }
?.map { it.value }
?.filter { it.startsWith("https://") || it.startsWith("http://") }

View File

@ -19,6 +19,7 @@ import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.api.session.pushers.PusherState
import org.matrix.android.sdk.internal.database.mapper.toEntity
import org.matrix.android.sdk.internal.database.model.PusherEntity
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
@ -41,7 +42,8 @@ internal class DefaultGetPushersTask @Inject constructor(
monarchy.awaitTransaction { realm ->
// clear existings?
realm.where(PusherEntity::class.java)
.findAll().deleteAllFromRealm()
.findAll()
.forEach { it.deleteOnCascade() }
response.pushers?.forEach { jsonPusher ->
jsonPusher.toEntity().also {
it.state = PusherState.REGISTERED

View File

@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.pushrules.RuleSetKey
import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse
import org.matrix.android.sdk.internal.database.mapper.PushRulesMapper
import org.matrix.android.sdk.internal.database.model.PushRulesEntity
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.task.Task
import org.matrix.android.sdk.internal.util.awaitTransaction
@ -40,7 +41,7 @@ internal class DefaultSavePushRulesTask @Inject constructor(@SessionDatabase pri
// clear current push rules
realm.where(PushRulesEntity::class.java)
.findAll()
.deleteAllFromRealm()
.forEach { it.deleteOnCascade() }
// Save only global rules for the moment
val globalRules = params.pushRules.global

View File

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.room.peeking
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomAvatarContent
@ -65,23 +66,29 @@ internal class DefaultPeekRoomTask @Inject constructor(
}
// Is it a public room?
val publicRepoResult = when (getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))) {
RoomDirectoryVisibility.PRIVATE -> {
// We cannot resolve this room :/
null
}
RoomDirectoryVisibility.PUBLIC -> {
val visibilityRes = tryOrNull("## PEEK: failed to get visibility") {
getRoomDirectoryVisibilityTask.execute(GetRoomDirectoryVisibilityTask.Params(roomId))
}
val publicRepoResult = when (visibilityRes) {
RoomDirectoryVisibility.PUBLIC -> {
// Try to find it in directory
val filter = if (isAlias) PublicRoomsFilter(searchTerm = params.roomIdOrAlias.substring(1))
else null
getPublicRoomTask.execute(GetPublicRoomTask.Params(
server = serverList.firstOrNull(),
publicRoomsParams = PublicRoomsParams(
filter = filter,
limit = 20.takeIf { filter != null } ?: 100
)
)).chunk?.firstOrNull { it.roomId == roomId }
tryOrNull("## PEEK: failed to GetPublicRoomTask") {
getPublicRoomTask.execute(GetPublicRoomTask.Params(
server = serverList.firstOrNull(),
publicRoomsParams = PublicRoomsParams(
filter = filter,
limit = 20.takeIf { filter != null } ?: 100
)
))
}?.chunk?.firstOrNull { it.roomId == roomId }
}
else -> {
// RoomDirectoryVisibility.PRIVATE or null
// We cannot resolve this room :/
null
}
}

View File

@ -22,16 +22,16 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.internal.database.helper.addOrUpdate
import org.matrix.android.sdk.internal.database.helper.addIfNecessary
import org.matrix.android.sdk.internal.database.helper.addStateEvent
import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
import org.matrix.android.sdk.internal.database.helper.deleteOnCascade
import org.matrix.android.sdk.internal.database.helper.merge
import org.matrix.android.sdk.internal.database.mapper.toEntity
import org.matrix.android.sdk.internal.database.model.ChunkEntity
import org.matrix.android.sdk.internal.database.model.EventInsertType
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
import org.matrix.android.sdk.internal.database.query.create
import org.matrix.android.sdk.internal.database.query.find
@ -172,7 +172,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
val currentLastForwardChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomId)
if (currentChunk != currentLastForwardChunk) {
currentChunk.isLastForward = true
currentLastForwardChunk?.deleteOnCascade()
currentLastForwardChunk?.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = false)
RoomSummaryEntity.where(realm, roomId).findFirst()?.apply {
latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
}
@ -235,7 +235,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
}
}
chunksToDelete.forEach {
it.deleteOnCascade()
it.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = false)
}
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
val shouldUpdateSummary = roomSummaryEntity.latestPreviewableEvent == null
@ -244,7 +244,7 @@ internal class TokenChunkEventPersistor @Inject constructor(@SessionDatabase pri
roomSummaryEntity.latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
}
if (currentChunk.isValid) {
RoomEntity.where(realm, roomId).findFirst()?.addOrUpdate(currentChunk)
RoomEntity.where(realm, roomId).findFirst()?.addIfNecessary(currentChunk)
}
}
}

View File

@ -30,9 +30,8 @@ import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
import org.matrix.android.sdk.internal.database.helper.addOrUpdate
import org.matrix.android.sdk.internal.database.helper.addIfNecessary
import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
import org.matrix.android.sdk.internal.database.helper.deleteOnCascade
import org.matrix.android.sdk.internal.database.mapper.asDomain
import org.matrix.android.sdk.internal.database.mapper.toEntity
import org.matrix.android.sdk.internal.database.model.ChunkEntity
@ -40,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
import org.matrix.android.sdk.internal.database.model.EventInsertType
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
import org.matrix.android.sdk.internal.database.query.find
import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfRoom
@ -48,6 +48,7 @@ import org.matrix.android.sdk.internal.database.query.getOrNull
import org.matrix.android.sdk.internal.database.query.where
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.extensions.clearWith
import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService
import org.matrix.android.sdk.internal.session.mapWithProgress
import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource
@ -177,7 +178,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
syncLocalTimestampMillis,
isInitialSync
)
roomEntity.addOrUpdate(chunkEntity)
roomEntity.addIfNecessary(chunkEntity)
}
val hasRoomMember = roomSync.state?.events?.firstOrNull {
it.type == EventType.STATE_ROOM_MEMBER
@ -265,7 +266,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
val leftMember = RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()
val membership = leftMember?.membership ?: Membership.LEAVE
roomEntity.membership = membership
roomEntity.chunks.deleteAllFromRealm()
roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) }
roomTypingUsersHandler.handle(realm, roomId, null)
roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE)
roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, roomSync.unreadNotifications)
@ -342,7 +343,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
}
}
// Finally delete the local echo
sendingEventEntity.deleteOnCascade()
sendingEventEntity.deleteOnCascade(true)
} else {
Timber.v("Can't find corresponding local echo for tx:$it")
}

View File

@ -16,8 +16,10 @@
package org.matrix.android.sdk.internal.session.sync
import com.squareup.moshi.Moshi
import com.zhuinden.monarchy.Monarchy
import io.realm.Realm
import io.realm.RealmList
import io.realm.kotlin.where
import org.matrix.android.sdk.api.pushrules.RuleScope
import org.matrix.android.sdk.api.pushrules.RuleSetKey
import org.matrix.android.sdk.api.pushrules.rest.GetPushRulesResponse
@ -37,6 +39,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.database.query.getDirectRooms
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.database.query.where
@ -50,9 +53,6 @@ import org.matrix.android.sdk.internal.session.sync.model.accountdata.IgnoredUse
import org.matrix.android.sdk.internal.session.sync.model.accountdata.UserAccountDataSync
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
import io.realm.Realm
import io.realm.RealmList
import io.realm.kotlin.where
import timber.log.Timber
import javax.inject.Inject
@ -60,7 +60,6 @@ internal class UserAccountDataSyncHandler @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
@UserId private val userId: String,
private val directChatsHelper: DirectChatsHelper,
private val moshi: Moshi,
private val updateUserAccountDataTask: UpdateUserAccountDataTask) {
fun handle(realm: Realm, accountData: UserAccountDataSync?) {
@ -113,7 +112,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
val pushRules = event.content.toModel<GetPushRulesResponse>() ?: return
realm.where(PushRulesEntity::class.java)
.findAll()
.deleteAllFromRealm()
.forEach { it.deleteOnCascade() }
// Save only global rules for the moment
val globalRules = pushRules.global

View File

@ -20,11 +20,12 @@ import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
import org.matrix.android.sdk.api.util.appendParamToUrl
import org.matrix.android.sdk.api.util.appendParamsToUrl
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask
import java.net.URLEncoder
import javax.inject.Inject
@SessionScope
@ -90,25 +91,4 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
}
return false
}
private fun StringBuilder.appendParamsToUrl(params: Map<String, String>): StringBuilder {
params.forEach { (param, value) ->
appendParamToUrl(param, value)
}
return this
}
private fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
if (contains("?")) {
append("&")
} else {
append("?")
}
append(param)
append("=")
append(URLEncoder.encode(value, "utf-8"))
return this
}
}

View File

@ -65,23 +65,31 @@ internal class WidgetFactory @Inject constructor(private val userDataSource: Use
)
}
// Ref: https://github.com/matrix-org/matrix-widget-api/blob/master/src/templating/url-template.ts#L29-L33
private fun WidgetContent.computeURL(roomId: String?, widgetId: String): String? {
var computedUrl = url ?: return null
val myUser = userDataSource.getUser(userId)
computedUrl = computedUrl
.replace("\$matrix_user_id", userId)
.replace("\$matrix_display_name", myUser?.displayName ?: userId)
.replace("\$matrix_avatar_url", myUser?.avatarUrl ?: "")
.replace("\$matrix_widget_id", widgetId)
if (roomId != null) {
computedUrl = computedUrl.replace("\$matrix_room_id", roomId)
}
for ((key, value) in data) {
if (value is String) {
computedUrl = computedUrl.replace("$$key", URLEncoder.encode(value, "utf-8"))
}
val keyValue = data.mapKeys { "\$${it.key}" }.toMutableMap()
keyValue[WIDGET_PATTERN_MATRIX_USER_ID] = userId
keyValue[WIDGET_PATTERN_MATRIX_DISPLAY_NAME] = myUser?.getBestName() ?: userId
keyValue[WIDGET_PATTERN_MATRIX_AVATAR_URL] = myUser?.avatarUrl ?: ""
keyValue[WIDGET_PATTERN_MATRIX_WIDGET_ID] = widgetId
keyValue[WIDGET_PATTERN_MATRIX_ROOM_ID] = roomId ?: ""
for ((key, value) in keyValue) {
computedUrl = computedUrl.replace(key, URLEncoder.encode(value.toString(), "utf-8"))
}
return computedUrl
}
companion object {
// Value to be replaced in URLS
const val WIDGET_PATTERN_MATRIX_USER_ID = "\$matrix_user_id"
const val WIDGET_PATTERN_MATRIX_DISPLAY_NAME = "\$matrix_display_name"
const val WIDGET_PATTERN_MATRIX_AVATAR_URL = "\$matrix_avatar_url"
const val WIDGET_PATTERN_MATRIX_WIDGET_ID = "\$matrix_widget_id"
const val WIDGET_PATTERN_MATRIX_ROOM_ID = "\$matrix_room_id"
}
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.android.sdk.internal.util
import androidx.core.text.HtmlCompat
internal fun String.unescapeHtml(): String {
return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_LEGACY).toString()
}

View File

@ -71,3 +71,10 @@ fun String.caseInsensitiveFind(subString: String): Boolean {
return false
}
internal val spaceChars = "[\u00A0\u2000-\u200B\u2800\u3000]".toRegex()
/**
* Strip all the UTF-8 chars which are actually spaces
*/
internal fun String.replaceSpaceChars() = replace(spaceChars, "")

View File

@ -12,8 +12,8 @@
<string name="notice_room_invite_you">%1$s t\'ha convidat</string>
<string name="notice_room_reject">%1$s ha rebutjat la invitació</string>
<string name="notice_room_kick">%1$s ha expulsat %2$s</string>
<string name="notice_display_name_changed_from">%1$s ha canviat el seu nom de visualització de %2$s a %3$s</string>
<string name="notice_display_name_removed">%1$s ha eliminat el seu nom de visualització (era %2$s)</string>
<string name="notice_display_name_changed_from">%1$s ha canviat el seu àlies de %2$s a %3$s</string>
<string name="notice_display_name_removed">%1$s ha eliminat el àlies (era %2$s)</string>
<string name="notice_room_topic_changed">%1$s ha canviat el tema a: %2$s</string>
<string name="notice_room_name_changed">%1$s ha canviat el nom de la sala a: %2$s</string>
<string name="notice_answered_call">%s ha respost a la trucada.</string>
@ -23,16 +23,16 @@
<string name="notice_room_visibility_unknown">desconegut (%s).</string>
<string name="notice_end_to_end">%1$s ha activat el xifrat d\'extrem a extrem (%2$s)</string>
<string name="notice_requested_voip_conference">%1$s ha sol·licitat una conferència VoIP</string>
<string name="notice_room_unban">%1$s ha tret el veto a %2$s</string>
<string name="notice_room_unban">%1$s ha tret el vet a %2$s</string>
<string name="notice_room_ban">%1$s ha vetat %2$s</string>
<string name="notice_room_withdraw">%1$s ha retirat la invitació de %2$s</string>
<string name="notice_avatar_url_changed">%1$s ha canviat el seu avatar</string>
<string name="notice_made_future_room_visibility">%1$s ha establert la visibilitat de l\'historial futur de la sala a %2$s</string>
<string name="notice_avatar_url_changed">%1$s ha canviat la seva icona</string>
<string name="notice_made_future_room_visibility">%1$s ha establert la visibilitat de l\'històric futur de la sala a %2$s</string>
<string name="notice_room_visibility_joined">tots els participants de la sala, des de que s\'hi uneixen.</string>
<string name="notice_room_visibility_world_readable">qualsevol.</string>
<string name="notice_voip_started">S\'ha iniciat la conferència VoIP</string>
<string name="notice_voip_finished">Ha finalitzat la conferència VoIP</string>
<string name="notice_avatar_changed_too">(també ha canviat l\'avatar)</string>
<string name="notice_avatar_changed_too">(també ha canviat la icona)</string>
<string name="notice_room_name_removed">%1$s ha eliminat el nom de la sala</string>
<string name="notice_room_topic_removed">%1$s ha eliminat el tema de la sala</string>
<string name="notice_profile_change_redacted">%1$s ha actualitzat el seu perfil %2$s</string>
@ -46,7 +46,7 @@
<string name="network_error">Error de xarxa</string>
<string name="matrix_error">Error de Matrix</string>
<string name="room_error_join_failed_empty_room">Ara per ara no és possible tornar a unir-se a una sala buida.</string>
<string name="notice_display_name_set">%1$s a canviat el seu nom de visualització a %2$s</string>
<string name="notice_display_name_set">%1$s a canviat el seu àlies a %2$s</string>
<string name="notice_placed_video_call">%s ha realitzat una videotrucada.</string>
<string name="notice_placed_voice_call">%s ha realitzat una trucada de veu.</string>
<!-- Room display name -->
@ -85,8 +85,8 @@
<item quantity="other">Has eliminat les adreces %1$s d\'aquesta sala.</item>
</plurals>
<plurals name="notice_room_aliases_removed">
<item quantity="one">%1$s ha eliminat l\'adreça %2$s d\'aquesta sala.</item>
<item quantity="other">%1$s ha eliminat les adreces %3$s d\'aquesta sala.</item>
<item quantity="one">%1$s ha eliminat %2$s com a adreça d\'aquesta sala.</item>
<item quantity="other">%1$s ha eliminat %2$s com a adreces d\'aquesta sala.</item>
</plurals>
<plurals name="notice_room_aliases_added_by_you">
<item quantity="one">Has afegit l\'adreça %1$s a aquesta sala.</item>
@ -110,8 +110,8 @@
<string name="notice_room_third_party_invite_with_reason">%1$s ha enviat una invitació a %2$s perquè s\'uneixi a la sala. Motiu: %3$s</string>
<string name="notice_room_ban_with_reason_by_you">Has vetat %1$s. Motiu: %2$s</string>
<string name="notice_room_ban_with_reason">%1$s ha vetat %2$s. Motiu: %3$s</string>
<string name="notice_room_unban_with_reason_by_you">Has tret el veto a %1$s. Motiu: %2$s</string>
<string name="notice_room_unban_with_reason">%1$s ha tret el veto a %2$s. Motiu: %3$s</string>
<string name="notice_room_unban_with_reason_by_you">Has tret el vet a %1$s. Motiu: %2$s</string>
<string name="notice_room_unban_with_reason">%1$s ha tret el vet a %2$s. Motiu: %3$s</string>
<string name="notice_room_ban_by_you">Has vetat %1$s</string>
<string name="notice_room_leave_with_reason_by_you">Has marxat de la sala. Motiu: %1$s</string>
<string name="notice_room_leave_with_reason">%1$s ha marxat de la sala. Motiu: %2$s</string>
@ -175,8 +175,8 @@
<string name="notice_event_redacted_with_reason">Missatge eliminat [motiu: %1$s]</string>
<string name="notice_event_redacted_by">Missatge eliminat per %1$s</string>
<string name="notice_event_redacted">Missatge eliminat</string>
<string name="notice_room_avatar_removed_by_you">Has eliminat l\'avatar de la sala</string>
<string name="notice_room_avatar_removed">%1$s ha eliminat l\'avatar de la sala</string>
<string name="notice_room_avatar_removed_by_you">Has eliminat la icona de la sala</string>
<string name="notice_room_avatar_removed">%1$s ha eliminat la icona de la sala</string>
<string name="notice_room_topic_removed_by_you">Has eliminat el tema de la sala</string>
<string name="notice_room_name_removed_by_you">Has eliminat el nom de la sala</string>
<string name="notice_requested_voip_conference_by_you">Has sol·licitat una conferència VoIP</string>
@ -185,7 +185,7 @@
<string name="notice_end_to_end_by_you">Has activat el xifrat d\'extrem a extrem (%1$s)</string>
<string name="notice_made_future_direct_room_visibility_by_you">Has establert la visibilitat dels missatges futurs a %1$s</string>
<string name="notice_made_future_direct_room_visibility">%1$s ha establert la visibilitat dels missatges futurs a %2$s</string>
<string name="notice_made_future_room_visibility_by_you">Has establert la visibilitat de l\'historial futur de la sala a %1$s</string>
<string name="notice_made_future_room_visibility_by_you">Has establert la visibilitat de l\'històric futur de la sala a %1$s</string>
<string name="notice_ended_call_by_you">Has finalitzat la trucada.</string>
<string name="notice_answered_call_by_you">Has respost a la trucada.</string>
<string name="notice_call_candidates_by_you">Has enviat dades per configurar la trucada.</string>
@ -193,15 +193,15 @@
<string name="notice_placed_voice_call_by_you">Has realitzat una trucada de veu.</string>
<string name="notice_placed_video_call_by_you">Has realitzat una videotrucada.</string>
<string name="notice_room_name_changed_by_you">Has canviat el nom de la sala a: %1$s</string>
<string name="notice_room_avatar_changed_by_you">Has canviat l\'avatar de la sala</string>
<string name="notice_room_avatar_changed">%1$s ha canviat l\'avatar de la sala</string>
<string name="notice_room_avatar_changed_by_you">Has canviat la icona de la sala</string>
<string name="notice_room_avatar_changed">%1$s ha canviat la icona de la sala</string>
<string name="notice_room_topic_changed_by_you">Has canviat el tema a: %1$s</string>
<string name="notice_display_name_removed_by_you">Has eliminat el teu nom de visualització (era %1$s)</string>
<string name="notice_display_name_changed_from_by_you">Has canviat el teu nom de visualització de %1$s a %2$s</string>
<string name="notice_display_name_set_by_you">Has canviat el teu nom de visualització a %1$s</string>
<string name="notice_avatar_url_changed_by_you">Has canviat el teu avatar</string>
<string name="notice_display_name_removed_by_you">Has eliminat el teu àlies (era %1$s)</string>
<string name="notice_display_name_changed_from_by_you">Has canviat el teu àlies de %1$s a %2$s</string>
<string name="notice_display_name_set_by_you">Has canviat el teu àlies a %1$s</string>
<string name="notice_avatar_url_changed_by_you">Has canviat la teva icona</string>
<string name="notice_room_withdraw_by_you">Has retirat la invitació de %1$s</string>
<string name="notice_room_unban_by_you">Has tret el veto a %1$s</string>
<string name="notice_room_unban_by_you">Has tret el vet a %1$s</string>
<string name="notice_room_reject_by_you">Has rebutjat la invitació</string>
<string name="notice_direct_room_created_by_you">Has creat la discussió</string>
<string name="notice_direct_room_created">%1$s ha creat la discussió</string>
@ -214,4 +214,49 @@
<string name="notice_room_invite_no_invitee_by_you">La teva invitació</string>
<string name="summary_you_sent_sticker">Has enviat un adhesiu.</string>
<string name="summary_you_sent_image">Has enviat una imatge.</string>
<string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Servidors coincidents amb literals IP ara estan vetats.</string>
<string name="notice_room_server_acl_updated_ip_literals_allowed">• Servidors coincidents amb literals IP ara estan permesos.</string>
<string name="notice_room_server_acl_updated_was_allowed">• Servidors coincidents amb %s han estat eliminats de la llista de permesos.</string>
<string name="notice_room_server_acl_updated_allowed">• Servidors coincidents amb %s ara estan permesos.</string>
<string name="notice_room_server_acl_updated_was_banned">• Servidors coincidents amb %s han estat eliminats del llista de vetats.</string>
<string name="notice_room_server_acl_updated_banned">• Servidors coincidents amb %s ara estan vetats.</string>
<string name="notice_room_server_acl_set_ip_literals_not_allowed">• Servidors coincidents amb literals IP estan vetats.</string>
<string name="notice_room_server_acl_set_ip_literals_allowed">• Servidors coincidents amb literals IP estan permesos.</string>
<string name="notice_room_server_acl_set_allowed">• Servidors coincidents amb %s estan permesos.</string>
<string name="notice_room_server_acl_set_banned">• Servidors coincidents amb %s estan vetats.</string>
<string name="notice_room_canonical_alias_no_change_by_you">Has canviat les adreces d\'aquesta sala.</string>
<string name="notice_room_canonical_alias_no_change">%1$s ha canviat les adreces d\'aquesta sala.</string>
<string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Has canviat l\'adreça principal i les adreces alternatives d\'aquesta sala.</string>
<string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s ha canviat l\'adreça principal i les adreces alternatives d\'aquesta sala.</string>
<string name="notice_room_canonical_alias_alternative_changed_by_you">Has canviat les adreces alternatives d\'aquesta sala.</string>
<string name="notice_room_canonical_alias_alternative_changed">%1$s ha canviat les adreces alternatives d\'aquesta sala.</string>
<plurals name="notice_room_canonical_alias_alternative_removed_by_you">
<item quantity="one">Has eliminat l\'adreça alternativa %1$s d\'aquesta sala.</item>
<item quantity="other">Has eliminat les adreces alternatives %1$s d\'aquesta sala.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_removed">
<item quantity="one">%1$s ha eliminat l\'adreça alternativa %2$s d\'aquesta sala.</item>
<item quantity="other">%1$s ha eliminat les adreces alternatives %2$s d\'aquesta sala.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_added_by_you">
<item quantity="one">Has afegit l\'adreça alternativa %1$s per aquesta sala.</item>
<item quantity="other">Has afegit les adreces alternatives %1$s per aquesta sala.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_added">
<item quantity="one">%1$s ha afegit l\'adreça alternativa %2$s per aquesta sala.</item>
<item quantity="other">%1$s ha afegit les adreces alternatives %2$s per aquesta sala.</item>
</plurals>
<string name="room_displayname_empty_room_was">Sala buida (era %s)</string>
<plurals name="room_displayname_four_and_more_members">
<item quantity="one">%1$s, %2$s, %3$s i %4$d altre</item>
<item quantity="other">%1$s, %2$s, %3$s i %4$d altres</item>
</plurals>
<string name="room_displayname_4_members">%1$s, %2$s, %3$s i %4$s</string>
<string name="room_displayname_3_members">%1$s, %2$s i %3$s</string>
<string name="notice_room_server_acl_allow_is_empty">🎉 Tots els servidors tenen la participació vetada! Aquesta sala ja no pot ser utilitzada.</string>
<string name="notice_room_server_acl_updated_no_change">Sense canvis.</string>
<string name="notice_room_server_acl_updated_title_by_you">Has canviat les ACLs de servidor d\'aquesta sala.</string>
<string name="notice_room_server_acl_updated_title">%s ha canviat les ACLs de servidor d\'aquesta sala.</string>
<string name="notice_room_server_acl_set_title_by_you">Has establert les ACLs de servidor per aquesta sala.</string>
<string name="notice_room_server_acl_set_title">%s ha establert les ACLs de servidor d\'aquesta sala.</string>
</resources>

View File

@ -73,8 +73,8 @@
\nImportuji místností, jichž jste členy</string>
<string name="initial_sync_start_importing_account_left_rooms">Úvodní synchronizace:
\nImportuji místnost, jež jste opustili</string>
<string name="initial_sync_start_importing_account_groups">Úvodní synchronizace:
\nImportuji komunity</string>
<string name="initial_sync_start_importing_account_groups">Úvodní synchronizace:
\nImportuji skupiny</string>
<string name="initial_sync_start_importing_account_data">Úvodní synchronizace:
\nImportuji data účtu</string>
<string name="event_status_sending_message">Odesílám zprávu…</string>
@ -90,7 +90,7 @@
<string name="summary_you_sent_sticker">Poslali jste nálepku.</string>
<string name="notice_room_invite_no_invitee_by_you">Vaše pozvání</string>
<string name="notice_room_created">%1$s založil místnost</string>
<string name="notice_room_created_by_you">Vy jste založili místnost</string>
<string name="notice_room_created_by_you">Založili jste místnost</string>
<string name="notice_room_invite_by_you">Pozvali jste %1$s</string>
<string name="notice_room_join_by_you">Vstoupili jste do místnosti</string>
<string name="notice_room_leave_by_you">Opustili jste místnost</string>
@ -204,11 +204,11 @@
<string name="notice_direct_room_leave_with_reason">%1$s odešli. Důvod: %2$s</string>
<string name="notice_direct_room_join_with_reason_by_you">Vstoupili jste. Důvod: %1$s</string>
<string name="notice_direct_room_join_with_reason">%1$s vstoupili. Důvod: %2$s</string>
<string name="notice_direct_room_third_party_revoked_invite_by_you">Vy jste zrušili pozvání pro %1$s</string>
<string name="notice_direct_room_third_party_revoked_invite_by_you">Zrušili jste pozvání pro %1$s</string>
<string name="notice_direct_room_third_party_revoked_invite">%1$s zrušili pozvání pro %2$s</string>
<string name="notice_direct_room_third_party_invite_by_you">Vy jste pozvali %1$s</string>
<string name="notice_direct_room_third_party_invite_by_you">Pozvali jste %1$s</string>
<string name="notice_direct_room_third_party_invite">%1$s pozvali %2$s</string>
<string name="notice_direct_room_update_by_you">Vy jste tady provedli upgrade.</string>
<string name="notice_direct_room_update_by_you">Tady jste provedli upgrade.</string>
<string name="notice_direct_room_update">%s tady provedli upgrade.</string>
<string name="notice_made_future_direct_room_visibility_by_you">Učinili jste budoucí zprávy viditelné pro %1$s</string>
<string name="notice_made_future_direct_room_visibility">%1$s učinili budoucí zprávy viditelné pro %2$s</string>

View File

@ -113,7 +113,7 @@
</plurals>
<string name="notice_room_aliases_added_and_removed">%1$s fügt %2$s als Adresse für diesen Raum hinzu und entfernt %3$s.</string>
<string name="notice_room_canonical_alias_set">%1$s legt die Hauptadresse fest für diesen Raum als %2$s fest.</string>
<string name="notice_room_canonical_alias_unset">%1$s entfernt die Hauptadresse für diesen Raum.</string>
<string name="notice_room_canonical_alias_unset">%1$s entfernte die Hauptadresse für diesen Raum.</string>
<string name="notice_room_guest_access_can_join">%1$s hat Gästen erlaubt den Raum zu betreten.</string>
<string name="notice_room_guest_access_forbidden">%1$s hat Gästen untersagt den Raum zu betreten.</string>
<string name="notice_end_to_end_ok">%1$s aktivierte Ende-zu-Ende-Verschlüsselung.</string>
@ -221,4 +221,49 @@
<string name="notice_direct_room_guest_access_forbidden">%1$s hat Gästen untersagt den Raum zu betreten.</string>
<string name="notice_direct_room_leave_with_reason_by_you">Du bist gegangen. Grund: %1$s</string>
<string name="notice_direct_room_leave_with_reason">%1$s ist gegangen. Grund: %2$s</string>
<string name="notice_room_canonical_alias_no_change_by_you">Du hast die Adressen für diesen Raum geändert.</string>
<string name="notice_room_canonical_alias_no_change">%1$s hat die Adressen für diesen Raum geändert.</string>
<string name="notice_room_canonical_alias_main_and_alternative_changed_by_you">Du hast die Haupt- und die alternativen Adressen für diesen Raum geändert.</string>
<string name="notice_room_canonical_alias_main_and_alternative_changed">%1$s hat die Haupt- und die alternativen Adressen für diesen Raum geändert.</string>
<string name="notice_room_canonical_alias_alternative_changed_by_you">Du hast die alternativen Adressen für diesen Raum geändert.</string>
<string name="notice_room_canonical_alias_alternative_changed">%1$s hat die alternativen Adressen für diesen Raum geändert.</string>
<plurals name="notice_room_canonical_alias_alternative_removed_by_you">
<item quantity="one">Du entferntest die alternative Adresse %1$s für diesen Raum.</item>
<item quantity="other">Du entferntest die alternativen Adressen %1$s für diesen Raum.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_removed">
<item quantity="one">%1$s entfernte die alternative Adresse %2$s für diesen Raum.</item>
<item quantity="other">%1$s entfernte die alternativen Adressen %2$s für diesen Raum.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_added_by_you">
<item quantity="one">Du fügtest die alternative Adresse %2$s für diesen Raum hinzu.</item>
<item quantity="other">Du fügtest die alternativen Adressen %2$s für diesen Raum hinzu.</item>
</plurals>
<plurals name="notice_room_canonical_alias_alternative_added">
<item quantity="one">%1$s fügte die alternative Adresse %2$s für diesen Raum hinzu.</item>
<item quantity="other">%1$s fügte die alternativen Adressen %2$s für diesen Raum hinzu.</item>
</plurals>
<string name="room_displayname_empty_room_was">Leerer Raum (war %s)</string>
<plurals name="room_displayname_four_and_more_members">
<item quantity="one">%1$s, %2$s, %3$s und %4$d andere/r</item>
<item quantity="other">%1$s, %2$s, %3$s und %4$d andere</item>
</plurals>
<string name="room_displayname_4_members">%1$s, %2$s, %3$s und %4$s</string>
<string name="room_displayname_3_members">%1$s, %2$s und %3$s</string>
<string name="notice_room_server_acl_allow_is_empty">🎉 Alle Server sind von der Teilnahme ausgeschlossen! Dieser Raum kann nicht mehr genutzt werden.</string>
<string name="notice_room_server_acl_updated_no_change">Keine Änderung.</string>
<string name="notice_room_server_acl_updated_ip_literals_not_allowed">• Server, die mit IPs übereinstimmen, sind jetzt gesperrt.</string>
<string name="notice_room_server_acl_updated_ip_literals_allowed">• Server, die mit IPs übereinstimmen, sind nicht erlaubt.</string>
<string name="notice_room_server_acl_updated_was_allowed">• Server, die mit %s übereinstimmen, wurden von der Elaubten-Liste entfernt.</string>
<string name="notice_room_server_acl_updated_allowed">• Server, die mit %s übereinstimmen, sind jetzt erlaubt.</string>
<string name="notice_room_server_acl_updated_was_banned">• Server, die mit %s übereinstimmen, werden von der Sperrliste entfernt.</string>
<string name="notice_room_server_acl_updated_banned">• Server, die mit %s übereinstimmen, sind jetzt gesperrt.</string>
<string name="notice_room_server_acl_updated_title_by_you">Du hast die Server-ACL für diesen Raum geändert.</string>
<string name="notice_room_server_acl_updated_title">%s hat die Server-Zugriffssteuerungsliste (ACL) für diesen Raum geändert.</string>
<string name="notice_room_server_acl_set_ip_literals_not_allowed">• Server, die mit IPs übereinstimmen, sind gesperrt.</string>
<string name="notice_room_server_acl_set_ip_literals_allowed">• Server, die mit IPs übereinstimmen, sind erlaubt.</string>
<string name="notice_room_server_acl_set_allowed">• Server, die mit %s übereinstimmen, sind erlaubt.</string>
<string name="notice_room_server_acl_set_banned">• Server, die mit %s übereinstimmen, sind gesperrt.</string>
<string name="notice_room_server_acl_set_title_by_you">Du hast die Server-ACL für diesen Raum gesetzt.</string>
<string name="notice_room_server_acl_set_title">%s hat die Server-Zugriffssteuerungsliste (ACL) für diesen Raum gesetzt.</string>
</resources>

View File

@ -1,13 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="medium_email">Enderezo de correo</string>
<string name="message_failed_to_upload">Fallo ao subir a páxina</string>
<string name="summary_message">%1$s: %2$s</string>
<string name="summary_user_sent_image">%1$s enviou unha imaxe.</string>
<string name="summary_user_sent_sticker">%1$s enviou unha icona.</string>
<string name="notice_room_invite_no_invitee">Convite de %s</string>
<string name="notice_room_invite">%1$s convidou a %2$s</string>
<string name="notice_room_invite_you">%1$s convidouno</string>
@ -35,34 +32,52 @@
<string name="notice_room_visibility_world_readable">todos.</string>
<string name="notice_room_visibility_unknown">descoñecido (%s).</string>
<string name="notice_end_to_end">%1$s activou a criptografía par-a-par (%2$s)</string>
<string name="notice_requested_voip_conference">%1$s solicitou unha conferencia VoIP</string>
<string name="notice_voip_started">A conferencia VoIP comenzou</string>
<string name="notice_voip_finished">A conferencia VoIP terminou</string>
<string name="notice_avatar_changed_too">(o avatar tamén foi cambiado)</string>
<string name="notice_room_name_removed">%1$s borrou o nome da sala</string>
<string name="notice_room_topic_removed">%1$s removeu o tema da sala</string>
<string name="notice_profile_change_redacted">%1$s actualizou o seu perfil %2$s</string>
<string name="notice_room_third_party_invite">%1$s envioulle un convite a %2$s para que entre na sala</string>
<string name="notice_room_third_party_registered_invite">%1$s aceptou o convite para %2$s</string>
<string name="notice_crypto_unable_to_decrypt">** Imposíbel descifrar: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">O dispositivo do que envía non enviou as chaves desta mensaxe.</string>
<string name="could_not_redact">Non se puido redactar</string>
<string name="unable_to_send_message">Non foi posíbel enviar a mensaxe</string>
<string name="network_error">Erro da conexión</string>
<string name="matrix_error">Erro de Matrix</string>
<string name="room_error_join_failed_empty_room">Aínda non é posíbel volver a entrar nunha sala baleira.</string>
<string name="encrypted_message">Mensaxe cifrada</string>
<string name="medium_phone_number">Número de teléfono</string>
<string name="room_displayname_two_members">%1$s e %2$s</string>
</resources>
<string name="notice_placed_voice_call_by_you">Fixeches unha chamada de audio.</string>
<string name="notice_placed_video_call_by_you">Fixeches unha chamada de vídeo.</string>
<string name="notice_room_name_changed_by_you">Cambiaches o nome da sala a: %1$s</string>
<string name="notice_room_avatar_changed_by_you">Cambiaches o avatar da sala</string>
<string name="notice_room_avatar_changed">%1$s cambiou o avatar da sala</string>
<string name="notice_room_topic_changed_by_you">Cambiaches o asunto a: %1$s</string>
<string name="notice_display_name_removed_by_you">Eliminaches o teu nome público (era %1$s)</string>
<string name="notice_display_name_changed_from_by_you">Cambiaches o teu nome público de %1$s a %2$s</string>
<string name="notice_display_name_set_by_you">Estableceches o nome público a %1$s</string>
<string name="notice_avatar_url_changed_by_you">Cambiaches o teu avatar</string>
<string name="notice_room_withdraw_by_you">Retirácheslle o convite a %1$s</string>
<string name="notice_room_ban_by_you">Vetaches a %1$s</string>
<string name="notice_room_unban_by_you">Readmitiches a %1$s</string>
<string name="notice_room_kick_by_you">Expulsaches a %1$s</string>
<string name="notice_room_reject_by_you">Rexeitaches o convite</string>
<string name="notice_direct_room_leave_by_you">Deixaches a sala</string>
<string name="notice_direct_room_leave">%1$s deixou a sala</string>
<string name="notice_room_leave_by_you">Saíches da sala</string>
<string name="notice_direct_room_join_by_you">Unícheste</string>
<string name="notice_direct_room_join">%1$s iniuse</string>
<string name="notice_room_join_by_you">Unícheste a sala</string>
<string name="notice_room_invite_by_you">Convidaches a %1$s</string>
<string name="notice_direct_room_created_by_you">Creaches a conversa</string>
<string name="notice_direct_room_created">%1$s creou a conversa</string>
<string name="notice_room_created_by_you">Creaches a sala</string>
<string name="notice_room_created">%1$s creou a sala</string>
<string name="notice_room_invite_no_invitee_by_you">O teu convite</string>
<string name="summary_you_sent_sticker">Enviaches un adhesivo.</string>
<string name="summary_you_sent_image">Enviaches unha imaxe.</string>
</resources>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

Some files were not shown because too many files have changed in this diff Show More