mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge develop into feature/db_clean_up
This commit is contained in:
commit
08cda2ee10
@ -10,6 +10,9 @@ Improvements 🙌:
|
||||
Bugfix 🐛:
|
||||
- Fix crash when coming from a notification (#1601)
|
||||
- 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 🗣:
|
||||
-
|
||||
@ -18,7 +21,9 @@ SDK API changes ⚠️:
|
||||
-
|
||||
|
||||
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:
|
||||
-
|
||||
|
@ -10,7 +10,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
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.airbnb.okreplay:gradle-plugin:1.5.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Fri Sep 27 10:10:35 CEST 2019
|
||||
#Thu Jul 02 12:33:07 CEST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
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
|
||||
|
@ -1,5 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="im.vector.matrix.android">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
@ -8,11 +7,6 @@
|
||||
|
||||
<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.
|
||||
Access to these file will be given via the FileService, with a temporary
|
||||
|
@ -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.TaskThread
|
||||
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.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.fetchCopied
|
||||
@ -340,7 +341,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
|
||||
fun ensureDevice() {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) {
|
||||
// Open the store
|
||||
cryptoStore.open()
|
||||
// TODO why do that everytime? we should mark that it was done
|
||||
|
@ -176,7 +176,6 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.root.getClearContent().toModel())
|
||||
val replyFormatted = REPLY_PATTERN.format(
|
||||
permalink,
|
||||
stringProvider.getString(R.string.message_reply_to_prefix),
|
||||
userLink,
|
||||
originalEvent.senderInfo.disambiguatedDisplayName,
|
||||
body.takeFormatted(),
|
||||
@ -371,7 +370,6 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
val body = bodyForReply(eventReplied.getLastMessageContent(), eventReplied.root.getClearContent().toModel())
|
||||
val replyFormatted = REPLY_PATTERN.format(
|
||||
permalink,
|
||||
stringProvider.getString(R.string.message_reply_to_prefix),
|
||||
userLink,
|
||||
userId,
|
||||
body.takeFormatted(),
|
||||
@ -433,10 +431,10 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
TextContent(content.body, formattedText)
|
||||
}
|
||||
}
|
||||
MessageType.MSGTYPE_FILE -> return TextContent(stringProvider.getString(R.string.reply_to_a_file))
|
||||
MessageType.MSGTYPE_AUDIO -> return TextContent(stringProvider.getString(R.string.reply_to_an_audio_file))
|
||||
MessageType.MSGTYPE_IMAGE -> return TextContent(stringProvider.getString(R.string.reply_to_an_image))
|
||||
MessageType.MSGTYPE_VIDEO -> return TextContent(stringProvider.getString(R.string.reply_to_a_video))
|
||||
MessageType.MSGTYPE_FILE -> return TextContent("sent a file.")
|
||||
MessageType.MSGTYPE_AUDIO -> return TextContent("sent an audio file.")
|
||||
MessageType.MSGTYPE_IMAGE -> return TextContent("sent an image.")
|
||||
MessageType.MSGTYPE_VIDEO -> return TextContent("sent a video.")
|
||||
else -> return TextContent(content?.body ?: "")
|
||||
}
|
||||
}
|
||||
@ -486,6 +484,6 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
// </blockquote>
|
||||
// </mx-reply>
|
||||
// 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"""
|
||||
}
|
||||
}
|
||||
|
@ -63,12 +63,6 @@
|
||||
<string name="summary_user_sent_sticker">أرسل %1$s ملصقا.</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_empty_room">غرفة فارغة</string>
|
||||
|
@ -52,8 +52,6 @@
|
||||
<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="message_reply_to_prefix">Cavab olaraq</string>
|
||||
|
||||
<string name="could_not_redact">Redaktə etmə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_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_room_invite">Otağa dəvət</string>
|
||||
|
||||
|
@ -63,13 +63,6 @@
|
||||
|
||||
<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_room_invite">Покана за стая</string>
|
||||
<string name="room_displayname_two_members">%1$s и %2$s</string>
|
||||
|
@ -76,11 +76,4 @@
|
||||
|
||||
<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>
|
||||
|
@ -46,8 +46,6 @@
|
||||
<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="message_reply_to_prefix">V odpovědi na</string>
|
||||
|
||||
<string name="could_not_redact">Nelze vymazat</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_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_room_invite">Pozvání do místnosti</string>
|
||||
|
||||
|
@ -73,13 +73,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Einladung von %s</string>
|
||||
<string name="room_displayname_room_invite">Raumeinladung</string>
|
||||
|
@ -40,8 +40,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** Αδυναμία αποκρυπτογράφησης: %s **</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="message_failed_to_upload">Αποτυχία αναφόρτωσης εικόνας</string>
|
||||
@ -56,10 +54,6 @@
|
||||
<string name="notice_voip_finished">Η VoIP διάσκεψη έληξε</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_room_invite">Πρόσκληση στο δωμάτιο</string>
|
||||
|
@ -17,8 +17,6 @@
|
||||
<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="message_reply_to_prefix">Responde al</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_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_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_room_invite">Ĉambra invito</string>
|
||||
|
||||
|
@ -73,13 +73,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Invitación de %s</string>
|
||||
<string name="room_displayname_room_invite">Invitación de Sala</string>
|
||||
|
@ -73,13 +73,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Invitación de %s</string>
|
||||
<string name="room_displayname_room_invite">Invitación a Sala</string>
|
||||
|
@ -50,8 +50,6 @@
|
||||
<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="message_reply_to_prefix">Vastuseks kasutajale</string>
|
||||
|
||||
<string name="could_not_redact">Ei saanud muuta sõnumit</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_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_room_invite">Kutse jututuppa</string>
|
||||
|
||||
|
@ -63,13 +63,6 @@
|
||||
|
||||
<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_room_invite">Gela gonbidapena</string>
|
||||
<string name="room_displayname_two_members">%1$s eta %2$s</string>
|
||||
|
@ -51,8 +51,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** ناتوان در رمزگشایی: %s **</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="message_failed_to_upload">شکست در بارگذاری تصویر</string>
|
||||
@ -67,11 +65,6 @@
|
||||
<string name="medium_email">نشانی رایانامه</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_room_invite">دعوت اتاق</string>
|
||||
|
||||
|
@ -70,13 +70,6 @@
|
||||
|
||||
<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">
|
||||
<item quantity="one">%1$s ja yksi muu</item>
|
||||
<item quantity="other">%1$s ja %2$d muuta</item>
|
||||
|
@ -63,13 +63,6 @@
|
||||
|
||||
<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_room_invite">Invitation au salon</string>
|
||||
<string name="room_displayname_empty_room">Salon vide</string>
|
||||
|
@ -50,8 +50,6 @@
|
||||
<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="message_reply_to_prefix">Respondéndolle a</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>
|
||||
|
||||
@ -64,11 +62,6 @@
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
|
@ -62,13 +62,6 @@
|
||||
|
||||
<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_room_invite">Meghívó egy szobába</string>
|
||||
<string name="room_displayname_two_members">%1$s és %2$s</string>
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
<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="message_reply_to_prefix">Sem svar til</string>
|
||||
|
||||
<string name="unable_to_send_message">Gat ekki sent skilaboð</string>
|
||||
|
||||
|
@ -62,13 +62,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Invito da %s</string>
|
||||
<string name="room_displayname_room_invite">Invito nella stanza</string>
|
||||
|
@ -56,8 +56,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** 解読できません: %s **</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="unable_to_send_message">メッセージを送信できません</string>
|
||||
|
||||
@ -73,9 +71,4 @@
|
||||
<string name="medium_email">メールアドレス</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>
|
||||
|
@ -52,8 +52,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** 암호를 복호화할 수 없음: %s **</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="unable_to_send_message">메시지를 보낼 수 없습니다</string>
|
||||
|
||||
@ -69,11 +67,6 @@
|
||||
<string name="medium_email">이메일 주소</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_room_invite">방 초대</string>
|
||||
|
||||
|
@ -71,13 +71,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Uitnodiging van %s</string>
|
||||
<string name="room_displayname_room_invite">Gespreksuitnodiging</string>
|
||||
|
@ -49,8 +49,6 @@
|
||||
<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="message_reply_to_prefix">Som svar til</string>
|
||||
|
||||
<string name="could_not_redact">Kunde ikkje gjera um</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_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_room_invite">Rominnbjoding</string>
|
||||
<string name="room_displayname_two_members">%1$s og %2$s</string>
|
||||
|
@ -42,7 +42,6 @@
|
||||
<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_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_room_invite">Zaproszenie do pokoju</string>
|
||||
@ -76,11 +75,6 @@
|
||||
<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="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_by">Wiadomość usunięta przez %1$s</string>
|
||||
<string name="notice_event_redacted_with_reason">Wiadomość usunięta [powód: %1$s]</string>
|
||||
|
@ -74,13 +74,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Convite de %s</string>
|
||||
<string name="room_displayname_room_invite">Convite para sala</string>
|
||||
|
@ -73,13 +73,6 @@
|
||||
|
||||
<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 -->
|
||||
<string name="room_displayname_invite_from">Приглашение от %s</string>
|
||||
<string name="room_displayname_room_invite">Приглашение в комнату</string>
|
||||
|
@ -62,13 +62,6 @@
|
||||
|
||||
<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_room_invite">Pozvanie do miestnosti</string>
|
||||
<string name="room_displayname_two_members">%1$s a %2$s</string>
|
||||
|
@ -34,8 +34,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** S’arrihet 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="message_reply_to_prefix">Në përgjigje të</string>
|
||||
|
||||
<string name="could_not_redact">S’u redaktua dot</string>
|
||||
<string name="unable_to_send_message">S’arrihet të dërgohet mesazh</string>
|
||||
|
||||
@ -51,11 +49,6 @@
|
||||
<string name="medium_email">Adresë email</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_room_invite">Ftesë Dhome</string>
|
||||
|
||||
|
@ -56,8 +56,6 @@
|
||||
<string name="notice_crypto_unable_to_decrypt">** Неможливо розшифрувати: %s **</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="unable_to_send_message">Не вдалося надіслати повідомлення</string>
|
||||
|
||||
@ -71,11 +69,6 @@
|
||||
<string name="medium_email">Адреса електронної пошти</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">
|
||||
<item quantity="one">%1$s та 1 інший</item>
|
||||
<item quantity="few">%1$s та %2$d інші</item>
|
||||
|
@ -50,8 +50,6 @@
|
||||
<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="message_reply_to_prefix">Als antwoord ip</string>
|
||||
|
||||
<string name="could_not_redact">Kosteg nie verwyderd wordn</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_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_room_invite">Gespreksuutnodigienge</string>
|
||||
|
||||
|
@ -63,13 +63,6 @@
|
||||
<string name="summary_message">%1$s:%2$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_invite_from">来自 %s 的邀请</string>
|
||||
<string name="room_displayname_room_invite">聊天室邀请</string>
|
||||
|
@ -62,13 +62,6 @@
|
||||
|
||||
<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_room_invite">聊天室邀請</string>
|
||||
<string name="room_displayname_two_members">%1$s 和 %2$s</string>
|
||||
|
@ -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>
|
||||
|
||||
<!-- Messages -->
|
||||
<string name="message_reply_to_prefix">In reply to</string>
|
||||
|
||||
<!-- Room Screen -->
|
||||
<string name="could_not_redact">Could not redact</string>
|
||||
@ -139,12 +138,6 @@
|
||||
<string name="medium_email">Email address</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 -->
|
||||
<string name="room_displayname_invite_from">Invite from %s</string>
|
||||
<string name="room_displayname_room_invite">Room Invite</string>
|
||||
|
@ -106,6 +106,11 @@ def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
|
||||
|
||||
android {
|
||||
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 {
|
||||
applicationId "im.vector.app"
|
||||
// Set to API 21: see #405
|
||||
@ -232,8 +237,7 @@ android {
|
||||
lintOptions {
|
||||
lintConfig file("lint.xml")
|
||||
|
||||
// TODO Restore true once pb with WorkManager is fixed
|
||||
abortOnError false
|
||||
abortOnError true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
|
@ -247,6 +247,12 @@
|
||||
|
||||
<!-- 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
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileProvider"
|
||||
|
@ -63,7 +63,13 @@ import java.util.Locale
|
||||
import java.util.concurrent.Executors
|
||||
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
|
||||
@Inject lateinit var legacySessionImporter: LegacySessionImporter
|
||||
@ -85,6 +91,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
|
||||
@Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager
|
||||
|
||||
lateinit var vectorComponent: VectorComponent
|
||||
|
||||
// font thread handler
|
||||
private var fontThreadHandler: Handler? = null
|
||||
|
||||
@ -157,7 +164,11 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
|
||||
|
||||
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 {
|
||||
return vectorComponent
|
||||
|
@ -17,29 +17,39 @@
|
||||
package im.vector.riotx.core.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.DownloadManager
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.Browser
|
||||
import android.provider.MediaStore
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.browser.customtabs.CustomTabsSession
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import im.vector.matrix.android.api.extensions.tryThis
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.features.notifications.NotificationUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import okio.source
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
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) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val externalContentUri: Uri
|
||||
val values = ContentValues()
|
||||
when {
|
||||
mediaMimeType?.startsWith("image/") == true -> {
|
||||
externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
values.put(MediaStore.Images.Media.TITLE, title)
|
||||
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 values = ContentValues().apply {
|
||||
put(MediaStore.Images.Media.TITLE, title)
|
||||
put(MediaStore.Images.Media.DISPLAY_NAME, title)
|
||||
put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
|
||||
put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
|
||||
put(MediaStore.Images.Media.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)
|
||||
if (uri == null) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
// TODO add notification?
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { mediaScanIntent ->
|
||||
mediaScanIntent.data = Uri.fromFile(file)
|
||||
context.sendBroadcast(mediaScanIntent)
|
||||
saveMediaLegacy(context, mediaMimeType, title, file)
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
*/
|
||||
@ -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() }
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ abstract class FormEditTextWithButtonItem : VectorEpoxyModel<FormEditTextWithBut
|
||||
}
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.textInputLayout.isEnabled = enabled
|
||||
holder.textInputLayout.hint = hint
|
||||
|
||||
|
@ -22,6 +22,7 @@ import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.text.Spannable
|
||||
@ -222,6 +223,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
|
||||
private const val AUDIO_CALL_PERMISSION_REQUEST_CODE = 1
|
||||
private const val VIDEO_CALL_PERMISSION_REQUEST_CODE = 2
|
||||
private const val SAVE_ATTACHEMENT_REQUEST_CODE = 3
|
||||
|
||||
/**
|
||||
* Sanitize the display name.
|
||||
@ -1194,17 +1196,12 @@ class RoomDetailFragment @Inject constructor(
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
if (allGranted(grantResults)) {
|
||||
when (requestCode) {
|
||||
// PERMISSION_REQUEST_CODE_DOWNLOAD_FILE -> {
|
||||
// val action = roomDetailViewModel.pendingAction
|
||||
// if (action != null) {
|
||||
// (action as? RoomDetailAction.DownloadFile)
|
||||
// ?.messageFileContent
|
||||
// ?.getFileName()
|
||||
// ?.let { showSnackWithMessage(getString(R.string.downloading_file, it)) }
|
||||
// roomDetailViewModel.pendingAction = null
|
||||
// roomDetailViewModel.handle(action)
|
||||
// }
|
||||
// }
|
||||
SAVE_ATTACHEMENT_REQUEST_CODE -> {
|
||||
sharedActionViewModel.pendingAction?.let {
|
||||
handleActions(it)
|
||||
sharedActionViewModel.pendingAction = null
|
||||
}
|
||||
}
|
||||
PERMISSION_REQUEST_CODE_INCOMING_URI -> {
|
||||
val pendingUri = roomDetailViewModel.pendingUri
|
||||
if (pendingUri != null) {
|
||||
@ -1357,6 +1354,11 @@ class RoomDetailFragment @Inject constructor(
|
||||
}
|
||||
|
||||
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(
|
||||
downloadMode = FileService.DownloadMode.FOR_EXTERNAL_SHARE,
|
||||
id = action.eventId,
|
||||
|
@ -21,4 +21,6 @@ import javax.inject.Inject
|
||||
/**
|
||||
* Activity shared view model to handle message actions
|
||||
*/
|
||||
class MessageSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<EventSharedAction>()
|
||||
class MessageSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<EventSharedAction>() {
|
||||
var pendingAction : EventSharedAction? = null
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user