Merge develop into feature/db_clean_up

This commit is contained in:
ganfra 2020-07-06 19:18:42 +02:00
commit 08cda2ee10
46 changed files with 213 additions and 296 deletions

View File

@ -10,6 +10,9 @@ Improvements 🙌:
Bugfix 🐛: Bugfix 🐛:
- Fix crash when coming from a notification (#1601) - Fix crash when coming from a notification (#1601)
- Fix Exception when importing keys (#1576) - Fix Exception when importing keys (#1576)
- File isn't downloaded when another file with the same name already exists (#1578)
- saved images don't show up in gallery (#1324)
- Fix reply fallback leaking sender locale (#429)
Translations 🗣: Translations 🗣:
- -
@ -18,7 +21,9 @@ SDK API changes ⚠️:
- -
Build 🧱: Build 🧱:
- - Fix lint false-positive about WorkManger (#1012)
- Upgrade build-tools from 3.5.3 to 3.6.6
- Upgrade gradle from 5.4.1 to 5.6.4
Other changes: Other changes:
- -

View File

@ -10,7 +10,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.google.gms:google-services:4.3.2' classpath 'com.google.gms:google-services:4.3.2'
classpath "com.airbnb.okreplay:gradle-plugin:1.5.0" classpath "com.airbnb.okreplay:gradle-plugin:1.5.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

View File

@ -1,6 +1,6 @@
#Fri Sep 27 10:10:35 CEST 2019 #Thu Jul 02 12:33:07 CEST 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="im.vector.matrix.android"> package="im.vector.matrix.android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@ -8,11 +7,6 @@
<application android:networkSecurityConfig="@xml/network_security_config"> <application android:networkSecurityConfig="@xml/network_security_config">
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />
<!-- <!--
The SDK offers a secured File provider to access downloaded files. The SDK offers a secured File provider to access downloaded files.
Access to these file will be given via the FileService, with a temporary Access to these file will be given via the FileService, with a temporary

View File

@ -98,6 +98,7 @@ import im.vector.matrix.android.internal.session.sync.model.SyncResponse
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.TaskThread import im.vector.matrix.android.internal.task.TaskThread
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.task.launchToCallback
import im.vector.matrix.android.internal.util.JsonCanonicalizer import im.vector.matrix.android.internal.util.JsonCanonicalizer
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.fetchCopied import im.vector.matrix.android.internal.util.fetchCopied
@ -340,7 +341,7 @@ internal class DefaultCryptoService @Inject constructor(
} }
fun ensureDevice() { fun ensureDevice() {
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) {
// Open the store // Open the store
cryptoStore.open() cryptoStore.open()
// TODO why do that everytime? we should mark that it was done // TODO why do that everytime? we should mark that it was done

View File

@ -176,7 +176,6 @@ internal class LocalEchoEventFactory @Inject constructor(
val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.root.getClearContent().toModel()) val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.root.getClearContent().toModel())
val replyFormatted = REPLY_PATTERN.format( val replyFormatted = REPLY_PATTERN.format(
permalink, permalink,
stringProvider.getString(R.string.message_reply_to_prefix),
userLink, userLink,
originalEvent.senderInfo.disambiguatedDisplayName, originalEvent.senderInfo.disambiguatedDisplayName,
body.takeFormatted(), body.takeFormatted(),
@ -371,7 +370,6 @@ internal class LocalEchoEventFactory @Inject constructor(
val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.root.getClearContent().toModel()) val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.root.getClearContent().toModel())
val replyFormatted = REPLY_PATTERN.format( val replyFormatted = REPLY_PATTERN.format(
permalink, permalink,
stringProvider.getString(R.string.message_reply_to_prefix),
userLink, userLink,
userId, userId,
body.takeFormatted(), body.takeFormatted(),
@ -433,10 +431,10 @@ internal class LocalEchoEventFactory @Inject constructor(
TextContent(content.body, formattedText) TextContent(content.body, formattedText)
} }
} }
MessageType.MSGTYPE_FILE -> return TextContent(stringProvider.getString(R.string.reply_to_a_file)) MessageType.MSGTYPE_FILE -> return TextContent("sent a file.")
MessageType.MSGTYPE_AUDIO -> return TextContent(stringProvider.getString(R.string.reply_to_an_audio_file)) MessageType.MSGTYPE_AUDIO -> return TextContent("sent an audio file.")
MessageType.MSGTYPE_IMAGE -> return TextContent(stringProvider.getString(R.string.reply_to_an_image)) MessageType.MSGTYPE_IMAGE -> return TextContent("sent an image.")
MessageType.MSGTYPE_VIDEO -> return TextContent(stringProvider.getString(R.string.reply_to_a_video)) MessageType.MSGTYPE_VIDEO -> return TextContent("sent a video.")
else -> return TextContent(content?.body ?: "") else -> return TextContent(content?.body ?: "")
} }
} }
@ -486,6 +484,6 @@ internal class LocalEchoEventFactory @Inject constructor(
// </blockquote> // </blockquote>
// </mx-reply> // </mx-reply>
// No whitespace because currently breaks temporary formatted text to Span // No whitespace because currently breaks temporary formatted text to Span
const val REPLY_PATTERN = """<mx-reply><blockquote><a href="%s">%s</a><a href="%s">%s</a><br />%s</blockquote></mx-reply>%s""" const val REPLY_PATTERN = """<mx-reply><blockquote><a href="%s">In reply to</a> <a href="%s">%s</a><br />%s</blockquote></mx-reply>%s"""
} }
} }

View File

@ -63,12 +63,6 @@
<string name="summary_user_sent_sticker">أرسل %1$s ملصقا.</string> <string name="summary_user_sent_sticker">أرسل %1$s ملصقا.</string>
<string name="notice_avatar_changed_too">(تغيّرت الصورة أيضا)</string> <string name="notice_avatar_changed_too">(تغيّرت الصورة أيضا)</string>
<string name="message_reply_to_prefix">ردا على</string>
<string name="reply_to_an_image">أرسل صورة.</string>
<string name="reply_to_a_video">أرسل فديوهًا.</string>
<string name="reply_to_an_audio_file">أرسل ملف صوت.</string>
<string name="reply_to_a_file">أرسل ملفًا.</string>
<string name="room_displayname_invite_from">دعوة من %s</string> <string name="room_displayname_invite_from">دعوة من %s</string>
<string name="room_displayname_empty_room">غرفة فارغة</string> <string name="room_displayname_empty_room">غرفة فارغة</string>

View File

@ -52,8 +52,6 @@
<string name="notice_crypto_unable_to_decrypt">** Şifrəni aça bilmir: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Şifrəni aça bilmir: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Göndərənin cihazı bu mesaj üçün açarları bizə göndərməyib.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Göndərənin cihazı bu mesaj üçün açarları bizə göndərməyib.</string>
<string name="message_reply_to_prefix">Cavab olaraq</string>
<string name="could_not_redact">Redaktə etmək olmur</string> <string name="could_not_redact">Redaktə etmək olmur</string>
<string name="unable_to_send_message">Mesaj göndərmək olmur</string> <string name="unable_to_send_message">Mesaj göndərmək olmur</string>
@ -69,11 +67,6 @@
<string name="medium_email">Elektron poçt ünvanı</string> <string name="medium_email">Elektron poçt ünvanı</string>
<string name="medium_phone_number">Telefon nömrəsi</string> <string name="medium_phone_number">Telefon nömrəsi</string>
<string name="reply_to_an_image">şəkil göndərdi.</string>
<string name="reply_to_a_video">video göndərdi.</string>
<string name="reply_to_an_audio_file">səs faylı göndərdi.</string>
<string name="reply_to_a_file">fayl göndərdi.</string>
<string name="room_displayname_invite_from">%s-dən dəvət</string> <string name="room_displayname_invite_from">%s-dən dəvət</string>
<string name="room_displayname_room_invite">Otağa dəvət</string> <string name="room_displayname_room_invite">Otağa dəvət</string>

View File

@ -63,13 +63,6 @@
<string name="summary_user_sent_sticker">%1$s изпрати стикер.</string> <string name="summary_user_sent_sticker">%1$s изпрати стикер.</string>
<string name="message_reply_to_prefix">В отговор на</string>
<string name="reply_to_an_image">изпрати снимка.</string>
<string name="reply_to_a_video">изпрати видео.</string>
<string name="reply_to_an_audio_file">изпрати аудио файл.</string>
<string name="reply_to_a_file">изпрати файл.</string>
<string name="room_displayname_invite_from">Покана от %s</string> <string name="room_displayname_invite_from">Покана от %s</string>
<string name="room_displayname_room_invite">Покана за стая</string> <string name="room_displayname_room_invite">Покана за стая</string>
<string name="room_displayname_two_members">%1$s и %2$s</string> <string name="room_displayname_two_members">%1$s и %2$s</string>

View File

@ -76,11 +76,4 @@
<string name="summary_user_sent_sticker">%1$s ha enviat un adhesiu.</string> <string name="summary_user_sent_sticker">%1$s ha enviat un adhesiu.</string>
<string name="message_reply_to_prefix">En resposta a</string>
<string name="reply_to_an_image">ha enviat una imatge.</string>
<string name="reply_to_a_video">ha enviat un vídeo.</string>
<string name="reply_to_an_audio_file">ha enviat un fitxer d\'àudio.</string>
<string name="reply_to_a_file">ha enviat un fitxer.</string>
</resources> </resources>

View File

@ -46,8 +46,6 @@
<string name="notice_crypto_unable_to_decrypt">** Nelze dešifrovat: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Nelze dešifrovat: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Odesílatelovo zařízení neposlalo klíče pro tuto zprávu.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Odesílatelovo zařízení neposlalo klíče pro tuto zprávu.</string>
<string name="message_reply_to_prefix">V odpovědi na</string>
<string name="could_not_redact">Nelze vymazat</string> <string name="could_not_redact">Nelze vymazat</string>
<string name="unable_to_send_message">Zprávu nelze odeslat</string> <string name="unable_to_send_message">Zprávu nelze odeslat</string>
@ -63,11 +61,6 @@
<string name="medium_email">E-mailová adresa</string> <string name="medium_email">E-mailová adresa</string>
<string name="medium_phone_number">Telefonní číslo</string> <string name="medium_phone_number">Telefonní číslo</string>
<string name="reply_to_an_image">odeslal obrázek.</string>
<string name="reply_to_a_video">odeslal video.</string>
<string name="reply_to_an_audio_file">odeslal zvukový soubor.</string>
<string name="reply_to_a_file">odeslal soubor.</string>
<string name="room_displayname_invite_from">Pozvání od %s</string> <string name="room_displayname_invite_from">Pozvání od %s</string>
<string name="room_displayname_room_invite">Pozvání do místnosti</string> <string name="room_displayname_room_invite">Pozvání do místnosti</string>

View File

@ -73,13 +73,6 @@
<string name="summary_user_sent_sticker">%1$s sandte einen Sticker.</string> <string name="summary_user_sent_sticker">%1$s sandte einen Sticker.</string>
<string name="message_reply_to_prefix">Als Antwort auf</string>
<string name="reply_to_an_image">hat ein Bild gesendet.</string>
<string name="reply_to_a_video">hat ein Video gesendet.</string>
<string name="reply_to_an_audio_file">hat eine Audio-Datei gesendet.</string>
<string name="reply_to_a_file">sandte eine Datei.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Einladung von %s</string> <string name="room_displayname_invite_from">Einladung von %s</string>
<string name="room_displayname_room_invite">Raumeinladung</string> <string name="room_displayname_room_invite">Raumeinladung</string>

View File

@ -40,8 +40,6 @@
<string name="notice_crypto_unable_to_decrypt">** Αδυναμία αποκρυπτογράφησης: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Αδυναμία αποκρυπτογράφησης: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Η συσκευή του/της αποστολέα δεν μας έχει στείλει τα κλειδιά για αυτό το μήνυμα.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Η συσκευή του/της αποστολέα δεν μας έχει στείλει τα κλειδιά για αυτό το μήνυμα.</string>
<string name="message_reply_to_prefix">Προς απάντηση στο</string>
<string name="unable_to_send_message">Αποτυχία αποστολής μηνύματος</string> <string name="unable_to_send_message">Αποτυχία αποστολής μηνύματος</string>
<string name="message_failed_to_upload">Αποτυχία αναφόρτωσης εικόνας</string> <string name="message_failed_to_upload">Αποτυχία αναφόρτωσης εικόνας</string>
@ -56,10 +54,6 @@
<string name="notice_voip_finished">Η VoIP διάσκεψη έληξε</string> <string name="notice_voip_finished">Η VoIP διάσκεψη έληξε</string>
<string name="notice_room_join">Ο/Η %1$s εισήλθε στο δωμάτιο</string> <string name="notice_room_join">Ο/Η %1$s εισήλθε στο δωμάτιο</string>
<string name="reply_to_an_image">έστειλε μία εικόνα.</string>
<string name="reply_to_a_video">έστειλε ένα βίντεο.</string>
<string name="reply_to_an_audio_file">έστειλε ένα αρχείο ήχου.</string>
<string name="reply_to_a_file">έστειλε ένα αρχείο.</string>
<string name="room_displayname_invite_from">Πρόσκληση από %s</string> <string name="room_displayname_invite_from">Πρόσκληση από %s</string>
<string name="room_displayname_room_invite">Πρόσκληση στο δωμάτιο</string> <string name="room_displayname_room_invite">Πρόσκληση στο δωμάτιο</string>

View File

@ -17,8 +17,6 @@
<string name="notice_crypto_unable_to_decrypt">** Ne eblas malĉifri: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Ne eblas malĉifri: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">La aparato de la sendanto ne sendis al ni la ŝlosilojn por tiu mesaĝo.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">La aparato de la sendanto ne sendis al ni la ŝlosilojn por tiu mesaĝo.</string>
<string name="message_reply_to_prefix">Responde al</string>
<string name="summary_message">%1$s: %2$s</string> <string name="summary_message">%1$s: %2$s</string>
<string name="notice_display_name_set">%1$s ŝanĝis sian vidigan nomon al %2$s</string> <string name="notice_display_name_set">%1$s ŝanĝis sian vidigan nomon al %2$s</string>
<string name="notice_display_name_changed_from">%1$s ŝanĝis sian vidigan nomon de %2$s al %3$s</string> <string name="notice_display_name_changed_from">%1$s ŝanĝis sian vidigan nomon de %2$s al %3$s</string>
@ -62,11 +60,6 @@
<string name="medium_email">Retpoŝtadreso</string> <string name="medium_email">Retpoŝtadreso</string>
<string name="medium_phone_number">Telefonnumero</string> <string name="medium_phone_number">Telefonnumero</string>
<string name="reply_to_an_image">sendis bildon.</string>
<string name="reply_to_a_video">sendis filmon.</string>
<string name="reply_to_an_audio_file">sendis sondosieron.</string>
<string name="reply_to_a_file">sendis dosieron.</string>
<string name="room_displayname_invite_from">Invito de %s</string> <string name="room_displayname_invite_from">Invito de %s</string>
<string name="room_displayname_room_invite">Ĉambra invito</string> <string name="room_displayname_room_invite">Ĉambra invito</string>

View File

@ -73,13 +73,6 @@
<string name="summary_user_sent_sticker">%1$s envió una calcomanía.</string> <string name="summary_user_sent_sticker">%1$s envió una calcomanía.</string>
<string name="message_reply_to_prefix">En respuesta a</string>
<string name="reply_to_an_image">envió una imagen.</string>
<string name="reply_to_a_video">envió un video.</string>
<string name="reply_to_an_audio_file">envió un archivo de audio.</string>
<string name="reply_to_a_file">envió un archivo.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Invitación de %s</string> <string name="room_displayname_invite_from">Invitación de %s</string>
<string name="room_displayname_room_invite">Invitación de Sala</string> <string name="room_displayname_room_invite">Invitación de Sala</string>

View File

@ -73,13 +73,6 @@
<string name="summary_user_sent_sticker">%1$s envió una pegatina.</string> <string name="summary_user_sent_sticker">%1$s envió una pegatina.</string>
<string name="message_reply_to_prefix">En respuesta a</string>
<string name="reply_to_an_image">envió una imagen.</string>
<string name="reply_to_a_video">envió un vídeo.</string>
<string name="reply_to_an_audio_file">envió un archivo de audio.</string>
<string name="reply_to_a_file">envió un archivo.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Invitación de %s</string> <string name="room_displayname_invite_from">Invitación de %s</string>
<string name="room_displayname_room_invite">Invitación a Sala</string> <string name="room_displayname_room_invite">Invitación a Sala</string>

View File

@ -50,8 +50,6 @@
<string name="notice_crypto_unable_to_decrypt">** Ei õnnestu dekrüptida: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Ei õnnestu dekrüptida: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Sõnumi saatja seade ei ole selle sõnumi jaoks saatnud dekrüptimisvõtmeid.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Sõnumi saatja seade ei ole selle sõnumi jaoks saatnud dekrüptimisvõtmeid.</string>
<string name="message_reply_to_prefix">Vastuseks kasutajale</string>
<string name="could_not_redact">Ei saanud muuta sõnumit</string> <string name="could_not_redact">Ei saanud muuta sõnumit</string>
<string name="unable_to_send_message">Sõnumi saatmine ei õnnestunud</string> <string name="unable_to_send_message">Sõnumi saatmine ei õnnestunud</string>
@ -67,11 +65,6 @@
<string name="medium_email">E-posti aadress</string> <string name="medium_email">E-posti aadress</string>
<string name="medium_phone_number">Telefoninumber</string> <string name="medium_phone_number">Telefoninumber</string>
<string name="reply_to_an_image">saatis pildi.</string>
<string name="reply_to_a_video">saatis video.</string>
<string name="reply_to_an_audio_file">saatis helifaili.</string>
<string name="reply_to_a_file">saatis faili.</string>
<string name="room_displayname_invite_from">Kutse kasutajalt %s</string> <string name="room_displayname_invite_from">Kutse kasutajalt %s</string>
<string name="room_displayname_room_invite">Kutse jututuppa</string> <string name="room_displayname_room_invite">Kutse jututuppa</string>

View File

@ -63,13 +63,6 @@
<string name="summary_user_sent_sticker">%1$s erabiltzaileak eranskailu bat bidali du.</string> <string name="summary_user_sent_sticker">%1$s erabiltzaileak eranskailu bat bidali du.</string>
<string name="message_reply_to_prefix">Honi erantzunez</string>
<string name="reply_to_an_image">irudi bat bidali du.</string>
<string name="reply_to_a_video">bideo bat bidali du.</string>
<string name="reply_to_an_audio_file">audio fitxategi bat bidali du.</string>
<string name="reply_to_a_file">fitxategi bat bidali du.</string>
<string name="room_displayname_invite_from">%s gelarako gonbidapena</string> <string name="room_displayname_invite_from">%s gelarako gonbidapena</string>
<string name="room_displayname_room_invite">Gela gonbidapena</string> <string name="room_displayname_room_invite">Gela gonbidapena</string>
<string name="room_displayname_two_members">%1$s eta %2$s</string> <string name="room_displayname_two_members">%1$s eta %2$s</string>

View File

@ -51,8 +51,6 @@
<string name="notice_crypto_unable_to_decrypt">** ناتوان در رمزگشایی: %s **</string> <string name="notice_crypto_unable_to_decrypt">** ناتوان در رمزگشایی: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">دستگاه فرستنده، کلیدهای این پیام را برایمان نفرستاده است.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">دستگاه فرستنده، کلیدهای این پیام را برایمان نفرستاده است.</string>
<string name="message_reply_to_prefix">در پاسخ به</string>
<string name="unable_to_send_message">ناتوان در فرستادن پیام</string> <string name="unable_to_send_message">ناتوان در فرستادن پیام</string>
<string name="message_failed_to_upload">شکست در بارگذاری تصویر</string> <string name="message_failed_to_upload">شکست در بارگذاری تصویر</string>
@ -67,11 +65,6 @@
<string name="medium_email">نشانی رایانامه</string> <string name="medium_email">نشانی رایانامه</string>
<string name="medium_phone_number">شماره تلفن</string> <string name="medium_phone_number">شماره تلفن</string>
<string name="reply_to_an_image">تصویری فرستاد.</string>
<string name="reply_to_a_video">ویدیویی فرستاد.</string>
<string name="reply_to_an_audio_file">پرونده‌ای صوتی فرستاد.</string>
<string name="reply_to_a_file">پرونده‌ای فرستاد.</string>
<string name="room_displayname_invite_from">دعوت از %s</string> <string name="room_displayname_invite_from">دعوت از %s</string>
<string name="room_displayname_room_invite">دعوت اتاق</string> <string name="room_displayname_room_invite">دعوت اتاق</string>

View File

@ -70,13 +70,6 @@
<string name="summary_user_sent_sticker">%1$s lähetti tarran.</string> <string name="summary_user_sent_sticker">%1$s lähetti tarran.</string>
<string name="message_reply_to_prefix">Vastauksena käyttäjälle</string>
<string name="reply_to_an_image">oli lähettänyt kuvan.</string>
<string name="reply_to_a_video">lähetti videon.</string>
<string name="reply_to_an_audio_file">lähetti äänitiedoston.</string>
<string name="reply_to_a_file">lähetti tiedoston.</string>
<plurals name="room_displayname_three_and_more_members"> <plurals name="room_displayname_three_and_more_members">
<item quantity="one">%1$s ja yksi muu</item> <item quantity="one">%1$s ja yksi muu</item>
<item quantity="other">%1$s ja %2$d muuta</item> <item quantity="other">%1$s ja %2$d muuta</item>

View File

@ -63,13 +63,6 @@
<string name="summary_user_sent_sticker">%1$s a envoyé un sticker.</string> <string name="summary_user_sent_sticker">%1$s a envoyé un sticker.</string>
<string name="message_reply_to_prefix">En réponse à</string>
<string name="reply_to_an_image">a envoyé une image.</string>
<string name="reply_to_a_video">a envoyé une vidéo.</string>
<string name="reply_to_an_audio_file">a envoyé un fichier audio.</string>
<string name="reply_to_a_file">a envoyé un fichier.</string>
<string name="room_displayname_invite_from">Invitation de %s</string> <string name="room_displayname_invite_from">Invitation de %s</string>
<string name="room_displayname_room_invite">Invitation au salon</string> <string name="room_displayname_room_invite">Invitation au salon</string>
<string name="room_displayname_empty_room">Salon vide</string> <string name="room_displayname_empty_room">Salon vide</string>

View File

@ -50,8 +50,6 @@
<string name="notice_crypto_unable_to_decrypt">** Imposíbel descifrar: %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="notice_crypto_error_unkwown_inbound_session_id">O dispositivo do que envía non enviou as chaves desta mensaxe.</string>
<string name="message_reply_to_prefix">Respondéndolle a</string>
<string name="could_not_redact">Non se puido redactar</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="unable_to_send_message">Non foi posíbel enviar a mensaxe</string>
@ -64,11 +62,6 @@
<string name="medium_phone_number">Número de teléfono</string> <string name="medium_phone_number">Número de teléfono</string>
<string name="reply_to_an_image">Responder a</string>
<string name="reply_to_a_video">enviar un vídeo.</string>
<string name="reply_to_an_audio_file">enviar un ficheiro de son.</string>
<string name="reply_to_a_file">enviar un ficheiro.</string>
<string name="room_displayname_two_members">%1$s e %2$s</string> <string name="room_displayname_two_members">%1$s e %2$s</string>

View File

@ -62,13 +62,6 @@
<string name="summary_user_sent_sticker">%1$s küldött egy matricát.</string> <string name="summary_user_sent_sticker">%1$s küldött egy matricát.</string>
<string name="message_reply_to_prefix">Válasz erre:</string>
<string name="reply_to_an_image">képet küldött.</string>
<string name="reply_to_a_video">videót küldött.</string>
<string name="reply_to_an_audio_file">hangfájlt küldött.</string>
<string name="reply_to_a_file">fájlt küldött.</string>
<string name="room_displayname_invite_from">Meghívó tőle: %s</string> <string name="room_displayname_invite_from">Meghívó tőle: %s</string>
<string name="room_displayname_room_invite">Meghívó egy szobába</string> <string name="room_displayname_room_invite">Meghívó egy szobába</string>
<string name="room_displayname_two_members">%1$s és %2$s</string> <string name="room_displayname_two_members">%1$s és %2$s</string>

View File

@ -24,7 +24,6 @@
<string name="notice_avatar_changed_too">(einnig var skipt um auðkennismynd)</string> <string name="notice_avatar_changed_too">(einnig var skipt um auðkennismynd)</string>
<string name="notice_crypto_unable_to_decrypt">** Mistókst að afkóða: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Mistókst að afkóða: %s **</string>
<string name="message_reply_to_prefix">Sem svar til</string>
<string name="unable_to_send_message">Gat ekki sent skilaboð</string> <string name="unable_to_send_message">Gat ekki sent skilaboð</string>

View File

@ -62,13 +62,6 @@
<string name="summary_user_sent_sticker">%1$s ha inviato un adesivo.</string> <string name="summary_user_sent_sticker">%1$s ha inviato un adesivo.</string>
<string name="message_reply_to_prefix">In risposta a</string>
<string name="reply_to_an_image">inviata un\'immagine.</string>
<string name="reply_to_a_video">inviato un video.</string>
<string name="reply_to_an_audio_file">inviato un file audio.</string>
<string name="reply_to_a_file">inviato un file.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Invito da %s</string> <string name="room_displayname_invite_from">Invito da %s</string>
<string name="room_displayname_room_invite">Invito nella stanza</string> <string name="room_displayname_room_invite">Invito nella stanza</string>

View File

@ -56,8 +56,6 @@
<string name="notice_crypto_unable_to_decrypt">** 解読できません: %s **</string> <string name="notice_crypto_unable_to_decrypt">** 解読できません: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">送信者の端末からこのメッセージのキーが送信されていません。</string> <string name="notice_crypto_error_unkwown_inbound_session_id">送信者の端末からこのメッセージのキーが送信されていません。</string>
<string name="message_reply_to_prefix">に返信</string>
<string name="could_not_redact">修正できませんでした</string> <string name="could_not_redact">修正できませんでした</string>
<string name="unable_to_send_message">メッセージを送信できません</string> <string name="unable_to_send_message">メッセージを送信できません</string>
@ -73,9 +71,4 @@
<string name="medium_email">メールアドレス</string> <string name="medium_email">メールアドレス</string>
<string name="medium_phone_number">電話番号</string> <string name="medium_phone_number">電話番号</string>
<string name="reply_to_an_image">画像を送信しました。</string>
<string name="reply_to_a_video">動画を送りました。</string>
<string name="reply_to_an_audio_file">音声ファイルを送信しました。</string>
<string name="reply_to_a_file">ファイルを送信しました。</string>
</resources> </resources>

View File

@ -52,8 +52,6 @@
<string name="notice_crypto_unable_to_decrypt">** 암호를 복호화할 수 없음: %s **</string> <string name="notice_crypto_unable_to_decrypt">** 암호를 복호화할 수 없음: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">발신인의 기기에서 이 메시지의 키를 보내지 않았습니다.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">발신인의 기기에서 이 메시지의 키를 보내지 않았습니다.</string>
<string name="message_reply_to_prefix">관련 대화</string>
<string name="could_not_redact">검열할 수 없습니다</string> <string name="could_not_redact">검열할 수 없습니다</string>
<string name="unable_to_send_message">메시지를 보낼 수 없습니다</string> <string name="unable_to_send_message">메시지를 보낼 수 없습니다</string>
@ -69,11 +67,6 @@
<string name="medium_email">이메일 주소</string> <string name="medium_email">이메일 주소</string>
<string name="medium_phone_number">전화번호</string> <string name="medium_phone_number">전화번호</string>
<string name="reply_to_an_image">사진을 보냈습니다.</string>
<string name="reply_to_a_video">동영상을 보냈습니다.</string>
<string name="reply_to_an_audio_file">오디오 파일을 보냈습니다.</string>
<string name="reply_to_a_file">파일을 보냈습니다.</string>
<string name="room_displayname_invite_from">%s에서 초대함</string> <string name="room_displayname_invite_from">%s에서 초대함</string>
<string name="room_displayname_room_invite">방 초대</string> <string name="room_displayname_room_invite">방 초대</string>

View File

@ -71,13 +71,6 @@
<string name="summary_user_sent_sticker">%1$s heeft een sticker gestuurd.</string> <string name="summary_user_sent_sticker">%1$s heeft een sticker gestuurd.</string>
<string name="message_reply_to_prefix">Als antwoord op</string>
<string name="reply_to_an_image">heeft een afbeelding gestuurd.</string>
<string name="reply_to_a_video">heeft een video gestuurd.</string>
<string name="reply_to_an_audio_file">heeft een audiobestand gestuurd.</string>
<string name="reply_to_a_file">heeft een bestand gestuurd.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Uitnodiging van %s</string> <string name="room_displayname_invite_from">Uitnodiging van %s</string>
<string name="room_displayname_room_invite">Gespreksuitnodiging</string> <string name="room_displayname_room_invite">Gespreksuitnodiging</string>

View File

@ -49,8 +49,6 @@
<string name="notice_crypto_unable_to_decrypt">** Fekk ikkje til å dekryptera: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Fekk ikkje til å dekryptera: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Avsendareiningi hev ikkje sendt oss nyklane fyr denna meldingi.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Avsendareiningi hev ikkje sendt oss nyklane fyr denna meldingi.</string>
<string name="message_reply_to_prefix">Som svar til</string>
<string name="could_not_redact">Kunde ikkje gjera um</string> <string name="could_not_redact">Kunde ikkje gjera um</string>
<string name="unable_to_send_message">Fekk ikkje å senda meldingi</string> <string name="unable_to_send_message">Fekk ikkje å senda meldingi</string>
@ -64,11 +62,6 @@
<string name="medium_email">Epostadresse</string> <string name="medium_email">Epostadresse</string>
<string name="medium_phone_number">Telefonnummer</string> <string name="medium_phone_number">Telefonnummer</string>
<string name="reply_to_an_image">sende eit bilæte.</string>
<string name="reply_to_a_video">sende ein video.</string>
<string name="reply_to_an_audio_file">sende ei ljodfil.</string>
<string name="reply_to_a_file">sende ei fil.</string>
<string name="room_displayname_invite_from">Innbjoding frå %s</string> <string name="room_displayname_invite_from">Innbjoding frå %s</string>
<string name="room_displayname_room_invite">Rominnbjoding</string> <string name="room_displayname_room_invite">Rominnbjoding</string>
<string name="room_displayname_two_members">%1$s og %2$s</string> <string name="room_displayname_two_members">%1$s og %2$s</string>

View File

@ -42,7 +42,6 @@
<string name="notice_room_withdraw">%1$s wycofał(a) zaproszenie %2$s</string> <string name="notice_room_withdraw">%1$s wycofał(a) zaproszenie %2$s</string>
<string name="notice_answered_call">%s odebrał(a) połączenie.</string> <string name="notice_answered_call">%s odebrał(a) połączenie.</string>
<string name="notice_avatar_changed_too">(awatar też został zmieniony)</string> <string name="notice_avatar_changed_too">(awatar też został zmieniony)</string>
<string name="message_reply_to_prefix">W odpowiedzi do</string>
<string name="room_displayname_invite_from">Zaproszenie od %s</string> <string name="room_displayname_invite_from">Zaproszenie od %s</string>
<string name="room_displayname_room_invite">Zaproszenie do pokoju</string> <string name="room_displayname_room_invite">Zaproszenie do pokoju</string>
@ -76,11 +75,6 @@
<string name="could_not_redact">Nie można zredagować</string> <string name="could_not_redact">Nie można zredagować</string>
<string name="room_error_join_failed_empty_room">Obecnie nie jest możliwe ponowne dołączenie do pustego pokoju.</string> <string name="room_error_join_failed_empty_room">Obecnie nie jest możliwe ponowne dołączenie do pustego pokoju.</string>
<string name="reply_to_an_image">wyślij zdjęcie.</string>
<string name="reply_to_a_video">wyślij wideo.</string>
<string name="reply_to_an_audio_file">wyślij plik audio.</string>
<string name="reply_to_a_file">wyślij plik.</string>
<string name="notice_event_redacted">Wiadomość usunięta</string> <string name="notice_event_redacted">Wiadomość usunięta</string>
<string name="notice_event_redacted_by">Wiadomość usunięta przez %1$s</string> <string name="notice_event_redacted_by">Wiadomość usunięta przez %1$s</string>
<string name="notice_event_redacted_with_reason">Wiadomość usunięta [powód: %1$s]</string> <string name="notice_event_redacted_with_reason">Wiadomość usunięta [powód: %1$s]</string>

View File

@ -74,13 +74,6 @@
<string name="summary_user_sent_sticker">%1$s enviou um sticker.</string> <string name="summary_user_sent_sticker">%1$s enviou um sticker.</string>
<string name="message_reply_to_prefix">Em resposta a</string>
<string name="reply_to_an_image">enviou uma imagem.</string>
<string name="reply_to_a_video">enviou um vídeo.</string>
<string name="reply_to_an_audio_file">enviou um arquivo de áudio.</string>
<string name="reply_to_a_file">enviou um arquivo.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Convite de %s</string> <string name="room_displayname_invite_from">Convite de %s</string>
<string name="room_displayname_room_invite">Convite para sala</string> <string name="room_displayname_room_invite">Convite para sala</string>

View File

@ -73,13 +73,6 @@
<string name="summary_user_sent_sticker">%1$s отправил стикер.</string> <string name="summary_user_sent_sticker">%1$s отправил стикер.</string>
<string name="message_reply_to_prefix">В ответ на</string>
<string name="reply_to_an_image">отправил изображение.</string>
<string name="reply_to_a_video">отправил видео.</string>
<string name="reply_to_an_audio_file">отправил аудиофайл.</string>
<string name="reply_to_a_file">отправил файл.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Приглашение от %s</string> <string name="room_displayname_invite_from">Приглашение от %s</string>
<string name="room_displayname_room_invite">Приглашение в комнату</string> <string name="room_displayname_room_invite">Приглашение в комнату</string>

View File

@ -62,13 +62,6 @@
<string name="summary_user_sent_sticker">%1$s poslal nálepku.</string> <string name="summary_user_sent_sticker">%1$s poslal nálepku.</string>
<string name="message_reply_to_prefix">Odpoveď na</string>
<string name="reply_to_an_image">odoslal obrázok.</string>
<string name="reply_to_a_video">odoslal video.</string>
<string name="reply_to_an_audio_file">odoslal zvukový súbor.</string>
<string name="reply_to_a_file">Odoslal súbor.</string>
<string name="room_displayname_invite_from">Pozvanie od %s</string> <string name="room_displayname_invite_from">Pozvanie od %s</string>
<string name="room_displayname_room_invite">Pozvanie do miestnosti</string> <string name="room_displayname_room_invite">Pozvanie do miestnosti</string>
<string name="room_displayname_two_members">%1$s a %2$s</string> <string name="room_displayname_two_members">%1$s a %2$s</string>

View File

@ -34,8 +34,6 @@
<string name="notice_crypto_unable_to_decrypt">** Sarrihet të shfshehtëzohet: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Sarrihet të shfshehtëzohet: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Pajisja e dërguesit nuk na ka dërguar kyçet për këtë mesazh.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Pajisja e dërguesit nuk na ka dërguar kyçet për këtë mesazh.</string>
<string name="message_reply_to_prefix">Në përgjigje të</string>
<string name="could_not_redact">Su redaktua dot</string> <string name="could_not_redact">Su redaktua dot</string>
<string name="unable_to_send_message">Sarrihet të dërgohet mesazh</string> <string name="unable_to_send_message">Sarrihet të dërgohet mesazh</string>
@ -51,11 +49,6 @@
<string name="medium_email">Adresë email</string> <string name="medium_email">Adresë email</string>
<string name="medium_phone_number">Numër telefoni</string> <string name="medium_phone_number">Numër telefoni</string>
<string name="reply_to_an_image">dërgoi një figurë.</string>
<string name="reply_to_a_video">dërgoi një video.</string>
<string name="reply_to_an_audio_file">dërgoi një kartelë audio.</string>
<string name="reply_to_a_file">dërgoi një kartelë.</string>
<string name="room_displayname_invite_from">Ftesë nga %s</string> <string name="room_displayname_invite_from">Ftesë nga %s</string>
<string name="room_displayname_room_invite">Ftesë Dhome</string> <string name="room_displayname_room_invite">Ftesë Dhome</string>

View File

@ -56,8 +56,6 @@
<string name="notice_crypto_unable_to_decrypt">** Неможливо розшифрувати: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Неможливо розшифрувати: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">Пристрій відправника не надіслав нам ключ для цього повідомлення.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">Пристрій відправника не надіслав нам ключ для цього повідомлення.</string>
<string name="message_reply_to_prefix">У відповідь на</string>
<string name="could_not_redact">Неможливо відредагувати</string> <string name="could_not_redact">Неможливо відредагувати</string>
<string name="unable_to_send_message">Не вдалося надіслати повідомлення</string> <string name="unable_to_send_message">Не вдалося надіслати повідомлення</string>
@ -71,11 +69,6 @@
<string name="medium_email">Адреса електронної пошти</string> <string name="medium_email">Адреса електронної пошти</string>
<string name="medium_phone_number">Номер телефону</string> <string name="medium_phone_number">Номер телефону</string>
<string name="reply_to_an_image">надіслав зображення.</string>
<string name="reply_to_a_video">надіслав відео.</string>
<string name="reply_to_an_audio_file">надіслав аудіо файл.</string>
<string name="reply_to_a_file">надіслав файл.</string>
<plurals name="room_displayname_three_and_more_members"> <plurals name="room_displayname_three_and_more_members">
<item quantity="one">%1$s та 1 інший</item> <item quantity="one">%1$s та 1 інший</item>
<item quantity="few">%1$s та %2$d інші</item> <item quantity="few">%1$s та %2$d інші</item>

View File

@ -50,8 +50,6 @@
<string name="notice_crypto_unable_to_decrypt">** Kun nie ountsleuteln: %s **</string> <string name="notice_crypto_unable_to_decrypt">** Kun nie ountsleuteln: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">t Toestel van den afzender èt geen sleutels vo da bericht hier gesteurd.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">t Toestel van den afzender èt geen sleutels vo da bericht hier gesteurd.</string>
<string name="message_reply_to_prefix">Als antwoord ip</string>
<string name="could_not_redact">Kosteg nie verwyderd wordn</string> <string name="could_not_redact">Kosteg nie verwyderd wordn</string>
<string name="unable_to_send_message">Kosteg t bericht nie verzendn</string> <string name="unable_to_send_message">Kosteg t bericht nie verzendn</string>
@ -67,11 +65,6 @@
<string name="medium_email">E-mailadresse</string> <string name="medium_email">E-mailadresse</string>
<string name="medium_phone_number">Telefongnumero</string> <string name="medium_phone_number">Telefongnumero</string>
<string name="reply_to_an_image">èt e fotootje gesteurd.</string>
<string name="reply_to_a_video">èt e filmtje gesteurd.</string>
<string name="reply_to_an_audio_file">èt e geluudsfragment gesteurd.</string>
<string name="reply_to_a_file">èt e bestand gesteurd.</string>
<string name="room_displayname_invite_from">Uutnodigienge van %s</string> <string name="room_displayname_invite_from">Uutnodigienge van %s</string>
<string name="room_displayname_room_invite">Gespreksuutnodigienge</string> <string name="room_displayname_room_invite">Gespreksuutnodigienge</string>

View File

@ -63,13 +63,6 @@
<string name="summary_message">%1$s%2$s</string> <string name="summary_message">%1$s%2$s</string>
<string name="summary_user_sent_sticker">%1$s 发送了一张贴纸。</string> <string name="summary_user_sent_sticker">%1$s 发送了一张贴纸。</string>
<string name="reply_to_an_image">发送了一张图片。</string>
<string name="reply_to_a_video">发送了一个视频。</string>
<string name="reply_to_an_audio_file">发送了一段音频。</string>
<string name="reply_to_a_file">发送了一个文件。</string>
<string name="message_reply_to_prefix">回复</string>
<string name="room_displayname_empty_room">空聊天室</string> <string name="room_displayname_empty_room">空聊天室</string>
<string name="room_displayname_invite_from">来自 %s 的邀请</string> <string name="room_displayname_invite_from">来自 %s 的邀请</string>
<string name="room_displayname_room_invite">聊天室邀请</string> <string name="room_displayname_room_invite">聊天室邀请</string>

View File

@ -62,13 +62,6 @@
<string name="summary_user_sent_sticker">%1$s 傳送了一張貼圖。</string> <string name="summary_user_sent_sticker">%1$s 傳送了一張貼圖。</string>
<string name="message_reply_to_prefix">回覆</string>
<string name="reply_to_an_image">傳送了圖片。</string>
<string name="reply_to_a_video">傳送了影片。</string>
<string name="reply_to_an_audio_file">傳送了音訊檔案。</string>
<string name="reply_to_a_file">傳送了檔案。</string>
<string name="room_displayname_invite_from">來自%s 的邀請</string> <string name="room_displayname_invite_from">來自%s 的邀請</string>
<string name="room_displayname_room_invite">聊天室邀請</string> <string name="room_displayname_room_invite">聊天室邀請</string>
<string name="room_displayname_two_members">%1$s 和 %2$s</string> <string name="room_displayname_two_members">%1$s 和 %2$s</string>

View File

@ -112,7 +112,6 @@
<string name="notice_crypto_error_unkwown_inbound_session_id">The sender\'s device has not sent us the keys for this message.</string> <string name="notice_crypto_error_unkwown_inbound_session_id">The sender\'s device has not sent us the keys for this message.</string>
<!-- Messages --> <!-- Messages -->
<string name="message_reply_to_prefix">In reply to</string>
<!-- Room Screen --> <!-- Room Screen -->
<string name="could_not_redact">Could not redact</string> <string name="could_not_redact">Could not redact</string>
@ -139,12 +138,6 @@
<string name="medium_email">Email address</string> <string name="medium_email">Email address</string>
<string name="medium_phone_number">Phone number</string> <string name="medium_phone_number">Phone number</string>
<!-- Reply to -->
<string name="reply_to_an_image">sent an image.</string>
<string name="reply_to_a_video">sent a video.</string>
<string name="reply_to_an_audio_file">sent an audio file.</string>
<string name="reply_to_a_file">sent a file.</string>
<!-- Room display name --> <!-- Room display name -->
<string name="room_displayname_invite_from">Invite from %s</string> <string name="room_displayname_invite_from">Invite from %s</string>
<string name="room_displayname_room_invite">Room Invite</string> <string name="room_displayname_room_invite">Room Invite</string>

View File

@ -106,6 +106,11 @@ def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
android { android {
compileSdkVersion 29 compileSdkVersion 29
// Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use
// Ref: https://issuetracker.google.com/issues/144111441
ndkVersion "21.3.6528147"
defaultConfig { defaultConfig {
applicationId "im.vector.app" applicationId "im.vector.app"
// Set to API 21: see #405 // Set to API 21: see #405
@ -232,8 +237,7 @@ android {
lintOptions { lintOptions {
lintConfig file("lint.xml") lintConfig file("lint.xml")
// TODO Restore true once pb with WorkManager is fixed abortOnError true
abortOnError false
} }
compileOptions { compileOptions {

View File

@ -247,6 +247,12 @@
<!-- Providers --> <!-- Providers -->
<!-- Remove WorkManagerInitializer Provider because we are using on-demand initialization of WorkManager-->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider" android:authorities="${applicationId}.fileProvider"

View File

@ -63,7 +63,13 @@ import java.util.Locale
import java.util.concurrent.Executors import java.util.concurrent.Executors
import javax.inject.Inject import javax.inject.Inject
class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.Provider, androidx.work.Configuration.Provider { import androidx.work.Configuration as WorkConfiguration
class VectorApplication :
Application(),
HasVectorInjector,
MatrixConfiguration.Provider,
WorkConfiguration.Provider {
lateinit var appContext: Context lateinit var appContext: Context
@Inject lateinit var legacySessionImporter: LegacySessionImporter @Inject lateinit var legacySessionImporter: LegacySessionImporter
@ -85,6 +91,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
@Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager @Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager
lateinit var vectorComponent: VectorComponent lateinit var vectorComponent: VectorComponent
// font thread handler // font thread handler
private var fontThreadHandler: Handler? = null private var fontThreadHandler: Handler? = null
@ -157,7 +164,11 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION) override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
override fun getWorkManagerConfiguration() = androidx.work.Configuration.Builder().setExecutor(Executors.newCachedThreadPool()).build() override fun getWorkManagerConfiguration(): WorkConfiguration {
return WorkConfiguration.Builder()
.setExecutor(Executors.newCachedThreadPool())
.build()
}
override fun injector(): VectorComponent { override fun injector(): VectorComponent {
return vectorComponent return vectorComponent

View File

@ -17,29 +17,39 @@
package im.vector.riotx.core.utils package im.vector.riotx.core.utils
import android.app.Activity import android.app.Activity
import android.app.DownloadManager
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment
import android.provider.Browser import android.provider.Browser
import android.provider.MediaStore import android.provider.MediaStore
import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsSession import androidx.browser.customtabs.CustomTabsSession
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import im.vector.matrix.android.api.extensions.tryThis
import im.vector.riotx.BuildConfig import im.vector.riotx.BuildConfig
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.features.notifications.NotificationUtils import im.vector.riotx.features.notifications.NotificationUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okio.buffer import okio.buffer
import okio.sink import okio.sink
import okio.source import okio.source
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -301,42 +311,20 @@ fun shareMedia(context: Context, file: File, mediaMimeType: String?) {
fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?, notificationUtils: NotificationUtils) { fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?, notificationUtils: NotificationUtils) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val externalContentUri: Uri val values = ContentValues().apply {
val values = ContentValues() put(MediaStore.Images.Media.TITLE, title)
when { put(MediaStore.Images.Media.DISPLAY_NAME, title)
mediaMimeType?.startsWith("image/") == true -> { put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Images.Media.TITLE, title) put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
values.put(MediaStore.Images.Media.DISPLAY_NAME, title)
values.put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
}
mediaMimeType?.startsWith("video/") == true -> {
externalContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
values.put(MediaStore.Video.Media.TITLE, title)
values.put(MediaStore.Video.Media.DISPLAY_NAME, title)
values.put(MediaStore.Video.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis())
}
mediaMimeType?.startsWith("audio/") == true -> {
externalContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
values.put(MediaStore.Audio.Media.TITLE, title)
values.put(MediaStore.Audio.Media.DISPLAY_NAME, title)
values.put(MediaStore.Audio.Media.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Audio.Media.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Audio.Media.DATE_TAKEN, System.currentTimeMillis())
}
else -> {
externalContentUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
values.put(MediaStore.Downloads.TITLE, title)
values.put(MediaStore.Downloads.DISPLAY_NAME, title)
values.put(MediaStore.Downloads.MIME_TYPE, mediaMimeType)
values.put(MediaStore.Downloads.DATE_ADDED, System.currentTimeMillis())
values.put(MediaStore.Downloads.DATE_TAKEN, System.currentTimeMillis())
}
} }
val externalContentUri = when {
mediaMimeType?.startsWith("image/") == true -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
mediaMimeType?.startsWith("video/") == true -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
mediaMimeType?.startsWith("audio/") == true -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
else -> MediaStore.Downloads.EXTERNAL_CONTENT_URI
}
val uri = context.contentResolver.insert(externalContentUri, values) val uri = context.contentResolver.insert(externalContentUri, values)
if (uri == null) { if (uri == null) {
Toast.makeText(context, R.string.error_saving_media_file, Toast.LENGTH_LONG).show() Toast.makeText(context, R.string.error_saving_media_file, Toast.LENGTH_LONG).show()
@ -357,16 +345,70 @@ fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String
notificationUtils.showNotificationMessage("DL", uri.hashCode(), notification) notificationUtils.showNotificationMessage("DL", uri.hashCode(), notification)
} }
} }
// TODO add notification?
} else { } else {
@Suppress("DEPRECATION") saveMediaLegacy(context, mediaMimeType, title, file)
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent -> }
mediaScanIntent.data = Uri.fromFile(file) }
context.sendBroadcast(mediaScanIntent)
@Suppress("DEPRECATION")
private fun saveMediaLegacy(context: Context, mediaMimeType: String?, title: String, file: File) {
val state = Environment.getExternalStorageState()
if (Environment.MEDIA_MOUNTED != state) {
context.toast(context.getString(R.string.error_saving_media_file))
return
}
GlobalScope.launch(Dispatchers.IO) {
val dest = when {
mediaMimeType?.startsWith("image/") == true -> Environment.DIRECTORY_PICTURES
mediaMimeType?.startsWith("video/") == true -> Environment.DIRECTORY_MOVIES
mediaMimeType?.startsWith("audio/") == true -> Environment.DIRECTORY_MUSIC
else -> Environment.DIRECTORY_DOWNLOADS
}
val downloadDir = Environment.getExternalStoragePublicDirectory(dest)
try {
val outputFilename = if (title.substringAfterLast('.', "").isEmpty()) {
val extension = mediaMimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) }
"$title.$extension"
} else {
title
}
val savedFile = saveFileIntoLegacy(file, downloadDir, outputFilename)
if (savedFile != null) {
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as? DownloadManager
downloadManager?.addCompletedDownload(
savedFile.name,
title,
true,
mediaMimeType ?: "application/octet-stream",
savedFile.absolutePath,
savedFile.length(),
true)
addToGallery(savedFile, mediaMimeType, context)
}
} catch (error: Throwable) {
GlobalScope.launch(Dispatchers.Main) {
context.toast(context.getString(R.string.error_saving_media_file))
}
} }
} }
} }
private fun addToGallery(savedFile: File, mediaMimeType: String?, context: Context) {
// MediaScannerConnection provides a way for applications to pass a newly created or downloaded media file to the media scanner service.
var mediaConnection: MediaScannerConnection? = null
val mediaScannerConnectionClient: MediaScannerConnection.MediaScannerConnectionClient = object : MediaScannerConnection.MediaScannerConnectionClient {
override fun onMediaScannerConnected() {
mediaConnection?.scanFile(savedFile.path, mediaMimeType)
}
override fun onScanCompleted(path: String, uri: Uri?) {
if (path == savedFile.path) mediaConnection?.disconnect()
}
}
mediaConnection = MediaScannerConnection(context, mediaScannerConnectionClient).apply { connect() }
}
/** /**
* Open the play store to the provided application Id, default to this app * Open the play store to the provided application Id, default to this app
*/ */
@ -381,3 +423,76 @@ fun openPlayStore(activity: Activity, appId: String = BuildConfig.APPLICATION_ID
} }
} }
} }
// ==============================================================================================================
// Media utils
// ==============================================================================================================
/**
* Copy a file into a dstPath directory.
* The output filename can be provided.
* The output file is not overridden if it is already exist.
*
* ~~ This is copied from the old matrix sdk ~~
*
* @param sourceFile the file source path
* @param dstDirPath the dst path
* @param outputFilename optional the output filename
* @param callback the asynchronous callback
*/
@Suppress("DEPRECATION")
fun saveFileIntoLegacy(sourceFile: File, dstDirPath: File, outputFilename: String?): File? {
// defines another name for the external media
val dstFileName: String
// build a filename is not provided
if (null == outputFilename) {
// extract the file extension from the uri
val dotPos = sourceFile.name.lastIndexOf(".")
var fileExt = ""
if (dotPos > 0) {
fileExt = sourceFile.name.substring(dotPos)
}
dstFileName = "vector_" + System.currentTimeMillis() + fileExt
} else {
dstFileName = outputFilename
}
var dstFile = File(dstDirPath, dstFileName)
// if the file already exists, append a marker
if (dstFile.exists()) {
var baseFileName = dstFileName
var fileExt = ""
val lastDotPos = dstFileName.lastIndexOf(".")
if (lastDotPos > 0) {
baseFileName = dstFileName.substring(0, lastDotPos)
fileExt = dstFileName.substring(lastDotPos)
}
var counter = 1
while (dstFile.exists()) {
dstFile = File(dstDirPath, "$baseFileName($counter)$fileExt")
counter++
}
}
// Copy source file to destination
var inputStream: FileInputStream? = null
var outputStream: FileOutputStream? = null
try {
dstFile.createNewFile()
inputStream = FileInputStream(sourceFile)
outputStream = FileOutputStream(dstFile)
val buffer = ByteArray(1024 * 10)
var len: Int
while (inputStream.read(buffer).also { len = it } != -1) {
outputStream.write(buffer, 0, len)
}
return dstFile
} catch (failure: Throwable) {
return null
} finally {
// Close resources
tryThis { inputStream?.close() }
tryThis { outputStream?.close() }
}
}

View File

@ -56,6 +56,7 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel<FormEditTextWithBut
} }
override fun bind(holder: Holder) { override fun bind(holder: Holder) {
super.bind(holder)
holder.textInputLayout.isEnabled = enabled holder.textInputLayout.isEnabled = enabled
holder.textInputLayout.hint = hint holder.textInputLayout.hint = hint

View File

@ -22,6 +22,7 @@ import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.text.Spannable import android.text.Spannable
@ -222,6 +223,7 @@ class RoomDetailFragment @Inject constructor(
private const val AUDIO_CALL_PERMISSION_REQUEST_CODE = 1 private const val AUDIO_CALL_PERMISSION_REQUEST_CODE = 1
private const val VIDEO_CALL_PERMISSION_REQUEST_CODE = 2 private const val VIDEO_CALL_PERMISSION_REQUEST_CODE = 2
private const val SAVE_ATTACHEMENT_REQUEST_CODE = 3
/** /**
* Sanitize the display name. * Sanitize the display name.
@ -1194,17 +1196,12 @@ class RoomDetailFragment @Inject constructor(
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (allGranted(grantResults)) { if (allGranted(grantResults)) {
when (requestCode) { when (requestCode) {
// PERMISSION_REQUEST_CODE_DOWNLOAD_FILE -> { SAVE_ATTACHEMENT_REQUEST_CODE -> {
// val action = roomDetailViewModel.pendingAction sharedActionViewModel.pendingAction?.let {
// if (action != null) { handleActions(it)
// (action as? RoomDetailAction.DownloadFile) sharedActionViewModel.pendingAction = null
// ?.messageFileContent }
// ?.getFileName() }
// ?.let { showSnackWithMessage(getString(R.string.downloading_file, it)) }
// roomDetailViewModel.pendingAction = null
// roomDetailViewModel.handle(action)
// }
// }
PERMISSION_REQUEST_CODE_INCOMING_URI -> { PERMISSION_REQUEST_CODE_INCOMING_URI -> {
val pendingUri = roomDetailViewModel.pendingUri val pendingUri = roomDetailViewModel.pendingUri
if (pendingUri != null) { if (pendingUri != null) {
@ -1357,6 +1354,11 @@ class RoomDetailFragment @Inject constructor(
} }
private fun onSaveActionClicked(action: EventSharedAction.Save) { private fun onSaveActionClicked(action: EventSharedAction.Save) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
&& !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, this, SAVE_ATTACHEMENT_REQUEST_CODE)) {
sharedActionViewModel.pendingAction = action
return
}
session.fileService().downloadFile( session.fileService().downloadFile(
downloadMode = FileService.DownloadMode.FOR_EXTERNAL_SHARE, downloadMode = FileService.DownloadMode.FOR_EXTERNAL_SHARE,
id = action.eventId, id = action.eventId,

View File

@ -21,4 +21,6 @@ import javax.inject.Inject
/** /**
* Activity shared view model to handle message actions * Activity shared view model to handle message actions
*/ */
class MessageSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<EventSharedAction>() class MessageSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<EventSharedAction>() {
var pendingAction : EventSharedAction? = null
}