diff --git a/android-smsmms/src/main/java/com/google/android/mms/ContentType.java b/android-smsmms/src/main/java/com/google/android/mms/ContentType.java index 9dad6c5e9..5bd6bd7b4 100755 --- a/android-smsmms/src/main/java/com/google/android/mms/ContentType.java +++ b/android-smsmms/src/main/java/com/google/android/mms/ContentType.java @@ -66,6 +66,7 @@ public class ContentType { public static final String AUDIO_3GPP = "audio/3gpp"; public static final String AUDIO_X_WAV = "audio/x-wav"; public static final String AUDIO_OGG = "application/ogg"; + public static final String AUDIO_OGG_ALT = "audio/ogg"; public static final String VIDEO_UNSPECIFIED = "video/*"; public static final String VIDEO_3GPP = "video/3gpp"; @@ -121,6 +122,7 @@ public class ContentType { sSupportedContentTypes.add(AUDIO_X_WAV); sSupportedContentTypes.add(AUDIO_3GPP); sSupportedContentTypes.add(AUDIO_OGG); + sSupportedContentTypes.add(AUDIO_OGG_ALT); sSupportedContentTypes.add(VIDEO_3GPP); sSupportedContentTypes.add(VIDEO_3G2); @@ -165,6 +167,7 @@ public class ContentType { sSupportedAudioTypes.add(AUDIO_X_WAV); sSupportedAudioTypes.add(AUDIO_3GPP); sSupportedAudioTypes.add(AUDIO_OGG); + sSupportedAudioTypes.add(AUDIO_OGG_ALT); // add supported video types sSupportedVideoTypes.add(VIDEO_3GPP); diff --git a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt index a5438d346..88d79d501 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/MessageRepositoryImpl.kt @@ -162,6 +162,8 @@ class MessageRepositoryImpl @Inject constructor( .contains("type", "image/") .or() .contains("type", "video/") + .or() + .contains("type", "audio/") .endGroup() .sort("id", Sort.DESCENDING) .findAllAsync() @@ -346,14 +348,20 @@ class MessageRepositoryImpl @Inject constructor( val maxHeight = smsManager.carrierConfigValues.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT) .takeIf { prefs.mmsSize.get() == -1 } ?: Int.MAX_VALUE - var remainingBytes = when (prefs.mmsSize.get()) { - -1 -> smsManager.carrierConfigValues.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE) + val carrierLimit = smsManager.carrierConfigValues.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE) + + val compressionLimit = when (prefs.mmsSize.get()) { + -1 -> carrierLimit 0 -> Int.MAX_VALUE else -> prefs.mmsSize.get() * 1024 } * 0.9 // Ugly, but buys us a bit of wiggle room + var bytesUsed = 0.0 + + var hasNotSkippedAttachment = true + signedBody.takeIf { it.isNotEmpty() }?.toByteArray()?.let { bytes -> - remainingBytes -= bytes.size + bytesUsed += bytes.size parts += MMSPart("text", ContentType.TEXT_PLAIN, bytes) } @@ -362,10 +370,53 @@ class MessageRepositoryImpl @Inject constructor( .mapNotNull { attachment -> attachment as? Attachment.Contact } .map { attachment -> attachment.vCard.toByteArray() } .map { vCard -> - remainingBytes -= vCard.size + bytesUsed += vCard.size MMSPart("contact", ContentType.TEXT_VCARD, vCard) } + val videoBytesByAttachment = attachments + .mapNotNull { attachment -> attachment as? Attachment.Video } + .associateWith { attachment -> + var uri = attachment.getUri() ?: return@associateWith byteArrayOf() + val inputStream = context.contentResolver.openInputStream(uri) ?: return@associateWith byteArrayOf() + inputStream.readBytes() + } + .toMutableMap() + + videoBytesByAttachment.forEach { (attachment, bytes) -> + val contentType: String = attachment.getContentType(context) ?: return@forEach + if (bytes.size < carrierLimit - bytesUsed) { + parts += MMSPart("video", contentType, bytes) + bytesUsed += bytes.size + } else { + Timber.w("Video file of ${bytes.size / 1024}Kb cannot be sent in ${(carrierLimit - bytesUsed).toInt() / 1024}Kb remaining space.") + hasNotSkippedAttachment = false + } + } + + val fileBytesByAttachment = attachments + .mapNotNull { attachment -> attachment as? Attachment.File } + .associateWith { attachment -> + val uri = attachment.getUri() ?: return@associateWith byteArrayOf() + val inputStream = context.contentResolver.openInputStream(uri) ?: return@associateWith byteArrayOf() + inputStream.readBytes() + } + .toMutableMap() + + fileBytesByAttachment.forEach { (attachment, bytes) -> + val contentType: String = attachment.getContentType(context) ?: return@forEach + if (contentType.let(ContentType::isSupportedAudioType)) { + if (bytes.size < carrierLimit - bytesUsed) { + parts += MMSPart(attachment.getName(context) + ?: "Attachment", contentType, bytes) + bytesUsed += bytes.size + } else { + Timber.w("File of ${bytes.size / 1024}Kb cannot be sent in ${(carrierLimit - bytesUsed).toInt() / 1024}Kb remaining space.") + hasNotSkippedAttachment = false + } + } + } + val imageBytesByAttachment = attachments .mapNotNull { attachment -> attachment as? Attachment.Image } .associateWith { attachment -> @@ -378,10 +429,10 @@ class MessageRepositoryImpl @Inject constructor( .toMutableMap() val imageByteCount = imageBytesByAttachment.values.sumBy { byteArray -> byteArray.size } - if (imageByteCount > remainingBytes) { + if (imageByteCount > compressionLimit - bytesUsed) { imageBytesByAttachment.forEach { (attachment, originalBytes) -> val uri = attachment.getUri() ?: return@forEach - val maxBytes = originalBytes.size / imageByteCount.toFloat() * remainingBytes + val maxBytes = originalBytes.size / imageByteCount.toFloat() * (compressionLimit - bytesUsed) // Get the image dimensions val options = BitmapFactory.Options().apply { inJustDecodeBounds = true } @@ -430,7 +481,10 @@ class MessageRepositoryImpl @Inject constructor( // We need to strip the separators from outgoing MMS, or else they'll appear to have sent and not go through val transaction = Transaction(context) val recipients = addresses.map(phoneNumberUtils::normalizeNumber) - transaction.sendNewMessage(subId, threadId, recipients, parts, null, null) + + if (parts.isNotEmpty() && hasNotSkippedAttachment) { + transaction.sendNewMessage(subId, threadId, recipients, parts, null, null) + } } } diff --git a/domain/src/main/java/com/moez/QKSMS/interactor/SendScheduledMessage.kt b/domain/src/main/java/com/moez/QKSMS/interactor/SendScheduledMessage.kt index 00a3ef091..91e97a9f0 100644 --- a/domain/src/main/java/com/moez/QKSMS/interactor/SendScheduledMessage.kt +++ b/domain/src/main/java/com/moez/QKSMS/interactor/SendScheduledMessage.kt @@ -47,7 +47,18 @@ class SendScheduledMessage @Inject constructor( } .map { message -> val threadId = TelephonyCompat.getOrCreateThreadId(context, message.recipients) - val attachments = message.attachments.mapNotNull(Uri::parse).map { Attachment.Image(it) } + val attachments = message.attachments.mapNotNull(Uri::parse).mapNotNull { uri -> + val contentType: String? = uri.let(context.contentResolver::getType) + if (contentType?.startsWith("image/") == true) { + Attachment.Image(uri) + } else if (contentType?.startsWith("video") == true) { + Attachment.Video(uri) + } else if (contentType != null) { + Attachment.File(uri) + } else { + null + } + } SendMessage.Params(message.subId, threadId, message.recipients, message.body, attachments) } .flatMap(sendMessage::buildObservable) diff --git a/domain/src/main/java/com/moez/QKSMS/model/Attachment.kt b/domain/src/main/java/com/moez/QKSMS/model/Attachment.kt index 07298feea..cb62cd95f 100644 --- a/domain/src/main/java/com/moez/QKSMS/model/Attachment.kt +++ b/domain/src/main/java/com/moez/QKSMS/model/Attachment.kt @@ -21,10 +21,10 @@ package com.moez.QKSMS.model import android.content.Context import android.net.Uri import android.os.Build +import android.provider.OpenableColumns import androidx.core.view.inputmethod.InputContentInfoCompat sealed class Attachment { - data class Image( private val uri: Uri? = null, private val inputContent: InputContentInfoCompat? = null @@ -47,8 +47,66 @@ sealed class Attachment { } } - data class Contact(val vCard: String) : Attachment() + data class Video( + private val uri: Uri? = null, + private val inputContent: InputContentInfoCompat? = null + ) : Attachment() { + fun getUri(): Uri? { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + inputContent?.contentUri ?: uri + } else { + uri + } + } + + fun getContentType(context: Context): String? { + return getUri()?.let(context.contentResolver::getType) + } + } + + data class File( + private val uri: Uri? = null, + private val inputContent: InputContentInfoCompat? = null + ) : Attachment() { + fun getUri(): Uri? { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + inputContent?.contentUri ?: uri + } else { + uri + } + } + + fun getContentType(context: Context): String? { + return getUri()?.let(context.contentResolver::getType) + } + + fun getName(context: Context): String? { + return getUri()?.let { + // The selection parameter can be null since the intent only opens one file. + returnUri -> + context.contentResolver.query(returnUri, arrayOf(OpenableColumns.DISPLAY_NAME), null, null, null) + }?.use { cursor -> + val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) + cursor.moveToFirst() + return cursor.getString(nameIndex) + } + } + + fun getSize(context: Context): Long? { + return getUri()?.let { + // The selection parameter can be null since the intent only opens one file. + returnUri -> + context.contentResolver.query(returnUri, arrayOf(OpenableColumns.SIZE), null, null, null) + }?.use { cursor -> + val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) + cursor.moveToFirst() + return cursor.getLong(sizeIndex) + } + } + } + + data class Contact(val vCard: String) : Attachment() } class Attachments(attachments: List) : List by attachments diff --git a/domain/src/main/java/com/moez/QKSMS/model/MmsPart.kt b/domain/src/main/java/com/moez/QKSMS/model/MmsPart.kt index aa3fa9082..c566c196c 100644 --- a/domain/src/main/java/com/moez/QKSMS/model/MmsPart.kt +++ b/domain/src/main/java/com/moez/QKSMS/model/MmsPart.kt @@ -44,6 +44,7 @@ open class MmsPart : RealmObject() { type == "text/x-vCard" -> "Contact card" type.startsWith("image") -> "Photo" type.startsWith("video") -> "Video" + type.startsWith("audio") -> "Audio" else -> null } diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index 796dc6a33..a03de1770 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -95,6 +95,26 @@ + + + + + + + + + + + + + + + + + + + + = PublishSubject.create() @@ -59,6 +64,11 @@ class AttachmentAdapter @Inject constructor( VIEW_TYPE_CONTACT -> inflater.inflate(R.layout.attachment_contact_list_item, parent, false) + VIEW_TYPE_VIDEO -> inflater.inflate(R.layout.attachment_image_list_item, parent, false) + .apply { thumbnailBounds.clipToOutline = true } + + VIEW_TYPE_FILE -> inflater.inflate(R.layout.attachment_file_list_item, parent, false) + else -> null!! // Impossible } @@ -87,12 +97,41 @@ class AttachmentAdapter @Inject constructor( holder.name?.text = displayName holder.name?.isVisible = displayName.isNotEmpty() } + is Attachment.Video -> { + GlideApp.with(context).load(attachment.getUri()).fitCenter().into(holder.thumbnail) + } + is Attachment.File -> { + Observable.just(attachment.getName(context)) + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { name -> + holder.filename?.text = name + holder.filename?.isVisible = name?.isNotEmpty() ?: false + } + Observable.just(attachment.getSize(context)) + .map { bytes -> + when (bytes) { + in 0..999 -> "$bytes B" + in 1000..999999 -> "${"%.1f".format(bytes / 1000f)} KB" + in 1000000..9999999 -> "${"%.1f".format(bytes / 1000000f)} MB" + else -> "${"%.1f".format(bytes / 1000000000f)} GB" + } + } + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { size -> + holder.size?.text = size + holder.size?.isVisible = size?.isNotEmpty() ?: false + } + } } } override fun getItemViewType(position: Int) = when (getItem(position)) { is Attachment.Image -> VIEW_TYPE_IMAGE is Attachment.Contact -> VIEW_TYPE_CONTACT + is Attachment.Video -> VIEW_TYPE_VIDEO + is Attachment.File -> VIEW_TYPE_FILE } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt index 3b42535b6..bec16a187 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt @@ -78,6 +78,8 @@ class ComposeActivity : QkThemedActivity(), ComposeView { private const val TakePhotoRequestCode = 1 private const val AttachPhotoRequestCode = 2 private const val AttachContactRequestCode = 3 + private const val AttachAudioRequestCode = 4 + private const val AttachVideoRequestCode = 5 private const val CameraDestinationKey = "camera_destination" } @@ -106,8 +108,12 @@ class ComposeActivity : QkThemedActivity(), ComposeView { override val galleryIntent by lazy { Observable.merge(gallery.clicks(), galleryLabel.clicks()) } override val scheduleIntent by lazy { Observable.merge(schedule.clicks(), scheduleLabel.clicks()) } override val attachContactIntent by lazy { Observable.merge(contact.clicks(), contactLabel.clicks()) } + override val attachAudioIntent by lazy { Observable.merge(audio.clicks(), audioLabel.clicks()) } + override val attachVideoIntent by lazy { Observable.merge(video.clicks(), videoLabel.clicks()) } override val attachmentSelectedIntent: Subject = PublishSubject.create() override val contactSelectedIntent: Subject = PublishSubject.create() + override val audioSelectedIntent: Subject = PublishSubject.create() + override val videoSelectedIntent: Subject = PublishSubject.create() override val inputContentIntent by lazy { message.inputContentSelected } override val scheduleSelectedIntent: Subject = PublishSubject.create() override val changeSimIntent by lazy { sim.clicks() } @@ -329,6 +335,28 @@ class ComposeActivity : QkThemedActivity(), ComposeView { startActivityForResult(Intent.createChooser(intent, null), AttachPhotoRequestCode) } + override fun requestAudio() { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + .addCategory(Intent.CATEGORY_OPENABLE) + .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false) + .addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) + .putExtra(Intent.EXTRA_LOCAL_ONLY, false) + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + .setType("audio/*") + startActivityForResult(Intent.createChooser(intent, null), AttachAudioRequestCode) + } + + override fun requestVideo() { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + .addCategory(Intent.CATEGORY_OPENABLE) + .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false) + .addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) + .putExtra(Intent.EXTRA_LOCAL_ONLY, false) + .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + .setType("video/*") + startActivityForResult(Intent.createChooser(intent, null), AttachVideoRequestCode) + } + override fun setDraft(draft: String) { message.setText(draft) message.setSelection(draft.length) @@ -380,6 +408,18 @@ class ComposeActivity : QkThemedActivity(), ComposeView { ?.forEach(attachmentSelectedIntent::onNext) ?: data?.data?.let(attachmentSelectedIntent::onNext) } + requestCode == AttachAudioRequestCode && resultCode == Activity.RESULT_OK -> { + data?.clipData?.itemCount?.let { count -> 0 until count } + ?.mapNotNull { i -> data.clipData?.getItemAt(i)?.uri } + ?.forEach(audioSelectedIntent::onNext) + ?: data?.data?.let(audioSelectedIntent::onNext) + } + requestCode == AttachVideoRequestCode && resultCode == Activity.RESULT_OK -> { + data?.clipData?.itemCount?.let { count -> 0 until count } + ?.mapNotNull { i -> data.clipData?.getItemAt(i)?.uri } + ?.forEach(videoSelectedIntent::onNext) + ?: data?.data?.let(videoSelectedIntent::onNext) + } requestCode == AttachContactRequestCode && resultCode == Activity.RESULT_OK -> { data?.data?.let(contactSelectedIntent::onNext) } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt index 8368dfa81..734f85e5e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivityModule.kt @@ -91,6 +91,14 @@ class ComposeActivityModule { text?.let(Attachment::Contact) } + ContentType.isVideoType(mimeType) -> { + Attachment.Video(uri) + } + + ContentType.isSupportedType(mimeType) -> { + Attachment.File(uri) + } + else -> null } }) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt index d8a78eec2..5e11f3266 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt @@ -46,8 +46,12 @@ interface ComposeView : QkView { val galleryIntent: Observable<*> val scheduleIntent: Observable<*> val attachContactIntent: Observable<*> + val attachAudioIntent: Observable<*> + val attachVideoIntent: Observable<*> val attachmentSelectedIntent: Observable val contactSelectedIntent: Observable + val audioSelectedIntent: Observable + val videoSelectedIntent: Observable val inputContentIntent: Observable val scheduleSelectedIntent: Observable val scheduleCancelIntent: Observable<*> @@ -66,6 +70,8 @@ interface ComposeView : QkView { fun showKeyboard() fun requestCamera() fun requestGallery() + fun requestAudio() + fun requestVideo() fun requestDatePicker() fun requestContact() fun setDraft(draft: String) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt index ba601f2f7..8a6d937e3 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt @@ -509,6 +509,18 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe { view.requestGallery() } + // Attach an audio file + view.attachAudioIntent + .doOnNext { newState { copy(attaching = false) } } + .autoDisposable(view.scope()) + .subscribe { view.requestAudio() } + + // Attach a video file + view.attachVideoIntent + .doOnNext { newState { copy(attaching = false) } } + .autoDisposable(view.scope()) + .subscribe { view.requestVideo() } + // Choose a time to schedule the message view.scheduleIntent .doOnNext { newState { copy(attaching = false) } } @@ -528,6 +540,30 @@ class ComposeViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe { newState { copy(attaching = false) } } + Observable.merge( + view.audioSelectedIntent.map { uri -> + Attachment.File(uri) + }, + view.inputContentIntent.map { inputContent -> + Attachment.File(inputContent = inputContent) + }) + .withLatestFrom(attachments) { attachment, attachments -> attachments + attachment } + .doOnNext(attachments::onNext) + .autoDisposable(view.scope()) + .subscribe { newState { copy(attaching = false) } } + + Observable.merge( + view.videoSelectedIntent.map { uri -> + Attachment.Video(uri) + }, + view.inputContentIntent.map { inputContent -> + Attachment.Video(inputContent = inputContent) + }) + .withLatestFrom(attachments) { attachment, attachments -> attachments + attachment } + .doOnNext(attachments::onNext) + .autoDisposable(view.scope()) + .subscribe { newState { copy(attaching = false) } } + // Set the scheduled time view.scheduleSelectedIntent .filter { scheduled -> @@ -658,9 +694,14 @@ class ComposeViewModel @Inject constructor( state.scheduled != 0L -> { newState { copy(scheduled = 0) } val uris = attachments - .mapNotNull { it as? Attachment.Image } - .map { it.getUri() } - .map { it.toString() } + .mapNotNull { attachment -> + when(attachment) { + is Attachment.Image -> attachment.getUri() + is Attachment.Video -> attachment.getUri() + is Attachment.File -> attachment.getUri() + else -> null + } + }.mapNotNull { it.toString() } val params = AddScheduledMessage .Params(state.scheduled, subId, addresses, sendAsGroup, body, uris) addScheduledMessage.execute(params) diff --git a/presentation/src/main/res/drawable/ic_audiotrack_black_24dp.xml b/presentation/src/main/res/drawable/ic_audiotrack_black_24dp.xml new file mode 100644 index 000000000..d0822ea60 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_audiotrack_black_24dp.xml @@ -0,0 +1,27 @@ + + + + diff --git a/presentation/src/main/res/layout/attachment_file_list_item.xml b/presentation/src/main/res/layout/attachment_file_list_item.xml new file mode 100644 index 000000000..a378a0425 --- /dev/null +++ b/presentation/src/main/res/layout/attachment_file_list_item.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/layout/compose_activity.xml b/presentation/src/main/res/layout/compose_activity.xml index 19900e0ad..865b38465 100644 --- a/presentation/src/main/res/layout/compose_activity.xml +++ b/presentation/src/main/res/layout/compose_activity.xml @@ -367,7 +367,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" - app:constraint_referenced_ids="contact,contactLabel,schedule,scheduleLabel,gallery,galleryLabel,camera,cameraLabel,attachingBackground" /> + app:constraint_referenced_ids="contact,contactLabel,schedule,scheduleLabel,gallery,galleryLabel,camera,cameraLabel,attachingBackground,audio,audioLabel,video,videoLabel" /> @@ -516,6 +516,74 @@ app:layout_constraintStart_toEndOf="@id/gallery" app:layout_constraintTop_toTopOf="@id/camera" /> + + + + + + + + جدوِل الرسالة إرفاق جهة اتصال خطأ في قراءة جهة الاتصال + Attach audio + Attach a video تحديد الشريحة %s محددة، غيّر شريحة SIM diff --git a/presentation/src/main/res/values-bn/strings.xml b/presentation/src/main/res/values-bn/strings.xml index 6ec138164..afbc3aab2 100644 --- a/presentation/src/main/res/values-bn/strings.xml +++ b/presentation/src/main/res/values-bn/strings.xml @@ -123,6 +123,8 @@ বার্তা পাঠানোর সময়সূচি নির্ধারণ করো একটি পরিচিতি সংযুক্ত করুন পরিচিতি পড়তে ত্রুটি + Attach audio + Attach a video সিম %1$d (%2$s) নির্বাচিত নির্বাচিত, %s সিম কার্ড পরিবর্তন করুন diff --git a/presentation/src/main/res/values-cs/strings.xml b/presentation/src/main/res/values-cs/strings.xml index 44b236787..f6363e411 100644 --- a/presentation/src/main/res/values-cs/strings.xml +++ b/presentation/src/main/res/values-cs/strings.xml @@ -125,6 +125,8 @@ Naplánovat zprávu Přiložit kontakt Chyba čtení kontaktu + Attach audio + Attach a video Vybrána SIM %1$d (%2$s) %s vybráno, změňte SIM kartu diff --git a/presentation/src/main/res/values-da/strings.xml b/presentation/src/main/res/values-da/strings.xml index 94272bea9..b359d403a 100644 --- a/presentation/src/main/res/values-da/strings.xml +++ b/presentation/src/main/res/values-da/strings.xml @@ -123,6 +123,8 @@ Planlæg besked Vedhæft en kontakt Fejl ved læsning af kontakt + Attach audio + Attach a video SIM %1$d (%2$s) valgt %s valgt, skift SIM-kortet diff --git a/presentation/src/main/res/values-de/strings.xml b/presentation/src/main/res/values-de/strings.xml index f24e229e2..67b86a1d9 100644 --- a/presentation/src/main/res/values-de/strings.xml +++ b/presentation/src/main/res/values-de/strings.xml @@ -123,6 +123,8 @@ Plane Nachricht Kontakt anhängen Fehler beim Lesen des Kontaktes + Attach audio + Attach a video SIM %1$d (%2$s) ausgewählt %s ausgewählt, SIM-Karte ändern diff --git a/presentation/src/main/res/values-el/strings.xml b/presentation/src/main/res/values-el/strings.xml index 71b1bc8c7..7acd6c1b6 100644 --- a/presentation/src/main/res/values-el/strings.xml +++ b/presentation/src/main/res/values-el/strings.xml @@ -123,6 +123,8 @@ Προγραμματισμός μηνύματος Επισύναψη επαφής Πρόβλημα ανάγνωσης επαφής + Attach audio + Attach a video SIM %1$d (%2$s) selected Επελέγη το %s, αλλάξτε την κάρτα SIM @@ -247,7 +249,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Συγχρονισμός μηνυμάτων Επανασυγχρονισμός μηνυμάτων με τη βάση δεδομένων SMS του Android Σχετικά με το QKSMS diff --git a/presentation/src/main/res/values-es/strings.xml b/presentation/src/main/res/values-es/strings.xml index 781d25108..f6b164288 100644 --- a/presentation/src/main/res/values-es/strings.xml +++ b/presentation/src/main/res/values-es/strings.xml @@ -123,6 +123,8 @@ Programar mensaje Adjuntar un contacto Error al leer contacto + Attach audio + Attach a video SIM %1$d (%2$s) seleccionada %s seleccionado, cambia la tarjeta SIM diff --git a/presentation/src/main/res/values-fa/strings.xml b/presentation/src/main/res/values-fa/strings.xml index 8cd0b8e70..0af3903b0 100644 --- a/presentation/src/main/res/values-fa/strings.xml +++ b/presentation/src/main/res/values-fa/strings.xml @@ -123,6 +123,8 @@ زمان‌بندی پیام یک مخاطب پیوست کنید خطا در خواندن مخاطب + Attach audio + Attach a video سیم‌کارت %1$d (%2$s) انتخاب شد %s انتخاب شد، سیم‌کارت را عوض کنید diff --git a/presentation/src/main/res/values-fi/strings.xml b/presentation/src/main/res/values-fi/strings.xml index feb834ae5..0e7ca24b3 100644 --- a/presentation/src/main/res/values-fi/strings.xml +++ b/presentation/src/main/res/values-fi/strings.xml @@ -123,6 +123,8 @@ Ajoita viesti Liitä yhteystieto Yhteystiedon lukuvirhe + Attach audio + Attach a video SIM %1$d (%2$s) valittu %s valittu, vaihda SIM-korttia diff --git a/presentation/src/main/res/values-fr/strings.xml b/presentation/src/main/res/values-fr/strings.xml index a6e0db82e..39c0096ad 100644 --- a/presentation/src/main/res/values-fr/strings.xml +++ b/presentation/src/main/res/values-fr/strings.xml @@ -123,6 +123,8 @@ Programmer un message Joindre un contact Erreur de lecture du contact + Attach audio + Attach a video SIM %1$d (%2$s) sélectionnée %s sélectionné, changer la carte SIM diff --git a/presentation/src/main/res/values-hi/strings.xml b/presentation/src/main/res/values-hi/strings.xml index 3ffa4570c..1a2a8b3ad 100644 --- a/presentation/src/main/res/values-hi/strings.xml +++ b/presentation/src/main/res/values-hi/strings.xml @@ -123,6 +123,8 @@ संदेश अनुसूचित करें Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -247,7 +249,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS diff --git a/presentation/src/main/res/values-hr/strings.xml b/presentation/src/main/res/values-hr/strings.xml index d00984050..2f0a7d7d6 100644 --- a/presentation/src/main/res/values-hr/strings.xml +++ b/presentation/src/main/res/values-hr/strings.xml @@ -124,6 +124,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -250,7 +252,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Uskladi poruke Ponovno uskladite svoje poruke sa nativnom Android SMS bazom podataka O aplikaciji diff --git a/presentation/src/main/res/values-hu/strings.xml b/presentation/src/main/res/values-hu/strings.xml index 99c29c249..d725c9dab 100644 --- a/presentation/src/main/res/values-hu/strings.xml +++ b/presentation/src/main/res/values-hu/strings.xml @@ -123,6 +123,8 @@ Időzített küldés Személy hozzáadása Hiba a személy olvasása közben + Attach audio + Attach a video SIM %1$d (%2$s) selected %s kiválasztva, cserélj SIM kártyát diff --git a/presentation/src/main/res/values-in/strings.xml b/presentation/src/main/res/values-in/strings.xml index 6bab78459..ab45f63b3 100644 --- a/presentation/src/main/res/values-in/strings.xml +++ b/presentation/src/main/res/values-in/strings.xml @@ -122,6 +122,8 @@ Jadwalkan pesan Lampirkan kontak Galat membaca kontak + Attach audio + Attach a video SIM %1$d (%2$s) dipilih %s dipilih, ganti kartu SIM diff --git a/presentation/src/main/res/values-it/strings.xml b/presentation/src/main/res/values-it/strings.xml index 14fd3ba3e..949556a00 100644 --- a/presentation/src/main/res/values-it/strings.xml +++ b/presentation/src/main/res/values-it/strings.xml @@ -123,6 +123,8 @@ Pianifica messaggio Collegare un contatto Errore nella lettura del contatto + Attach audio + Attach a video SIM %1$d (%2$s) selezionata %s selezionato, cambiare SIM diff --git a/presentation/src/main/res/values-iw/strings.xml b/presentation/src/main/res/values-iw/strings.xml index ad00c6106..6c0f16d15 100644 --- a/presentation/src/main/res/values-iw/strings.xml +++ b/presentation/src/main/res/values-iw/strings.xml @@ -125,6 +125,8 @@ תזמון הודעה צרף איש קשר שגיאה בקריאת איש קשר + Attach audio + Attach a video נבחר SIM מס׳ %1$d ‏(%2$s) %s נבחר, החלף כרטיס SIM diff --git a/presentation/src/main/res/values-ja/strings.xml b/presentation/src/main/res/values-ja/strings.xml index 0bd3df743..6012f1e3d 100644 --- a/presentation/src/main/res/values-ja/strings.xml +++ b/presentation/src/main/res/values-ja/strings.xml @@ -122,6 +122,8 @@ スケジュールメッセージ 連絡先を添付する 連絡先の読み取りエラー + Attach audio + Attach a video SIM %1$d (%2$s) を選択しました %s 選択、SIMカードを交換 diff --git a/presentation/src/main/res/values-ko/strings.xml b/presentation/src/main/res/values-ko/strings.xml index 0a70241ef..adf6aa08f 100644 --- a/presentation/src/main/res/values-ko/strings.xml +++ b/presentation/src/main/res/values-ko/strings.xml @@ -122,6 +122,8 @@ 예약 전송 메시지 연락처 첨부 연락처를 불러오는 중에 문제가 발생했습니다 + Attach audio + Attach a video SIM %1$d (%2$s) 선택 됨 %s 선택됨, SIM 카드를 변경하세요. diff --git a/presentation/src/main/res/values-lt/strings.xml b/presentation/src/main/res/values-lt/strings.xml index f739bb27e..44a83860e 100644 --- a/presentation/src/main/res/values-lt/strings.xml +++ b/presentation/src/main/res/values-lt/strings.xml @@ -125,6 +125,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -253,7 +255,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sinchronizuoti pranešimus Iš naujo sinchronizuoti Android pranešimų duomenų bazę Apie QKSMS diff --git a/presentation/src/main/res/values-nb/strings.xml b/presentation/src/main/res/values-nb/strings.xml index 5725c06eb..5a72bd37d 100644 --- a/presentation/src/main/res/values-nb/strings.xml +++ b/presentation/src/main/res/values-nb/strings.xml @@ -123,6 +123,8 @@ Planlegg melding Legg til kontakt Feil ved åpning av kontakt + Attach audio + Attach a video SIM %1$d (%2$s) selected %s er valgt, velg annet SIM-kort diff --git a/presentation/src/main/res/values-ne/strings.xml b/presentation/src/main/res/values-ne/strings.xml index 98a76c069..29613a666 100644 --- a/presentation/src/main/res/values-ne/strings.xml +++ b/presentation/src/main/res/values-ne/strings.xml @@ -123,6 +123,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -247,7 +249,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS diff --git a/presentation/src/main/res/values-nl/strings.xml b/presentation/src/main/res/values-nl/strings.xml index e7f3bc758..492189c4a 100644 --- a/presentation/src/main/res/values-nl/strings.xml +++ b/presentation/src/main/res/values-nl/strings.xml @@ -123,6 +123,8 @@ Bericht plannen Een contactpersoon toevoegen Fout bij het lezen van contact + Attach audio + Attach a video Simkaart %1$d (%2$s) geselecteerd %s geselecteerd, wijzig SIM-kaart diff --git a/presentation/src/main/res/values-pl/strings.xml b/presentation/src/main/res/values-pl/strings.xml index f8af2c1f3..7330cb2da 100644 --- a/presentation/src/main/res/values-pl/strings.xml +++ b/presentation/src/main/res/values-pl/strings.xml @@ -125,6 +125,8 @@ Zaplanuj wiadomość Załącz kontakt Nie można odczytać kontaktu + Attach audio + Attach a video Wybrano kartę SIM %1$d (%2$s) Wybrano %s, zmień kartę SIM diff --git a/presentation/src/main/res/values-pt-rBR/strings.xml b/presentation/src/main/res/values-pt-rBR/strings.xml index 941eb6a2a..81a5f7a4e 100644 --- a/presentation/src/main/res/values-pt-rBR/strings.xml +++ b/presentation/src/main/res/values-pt-rBR/strings.xml @@ -123,6 +123,8 @@ Agendar mensagem Anexar contato Erro ao ler contato + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selecionado, altere o cartão SIM diff --git a/presentation/src/main/res/values-pt/strings.xml b/presentation/src/main/res/values-pt/strings.xml index f4a4270d9..da2a085e0 100644 --- a/presentation/src/main/res/values-pt/strings.xml +++ b/presentation/src/main/res/values-pt/strings.xml @@ -123,6 +123,8 @@ Agendar mensagem Anexar um contacto Erro ao ler o contacto + Attach audio + Attach a video SIM %1$d (%2$s) selecionado %s selecionado, alterar cartão SIM diff --git a/presentation/src/main/res/values-ro/strings.xml b/presentation/src/main/res/values-ro/strings.xml index e4f3446d5..378ac9609 100644 --- a/presentation/src/main/res/values-ro/strings.xml +++ b/presentation/src/main/res/values-ro/strings.xml @@ -124,6 +124,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -250,7 +252,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS diff --git a/presentation/src/main/res/values-ru/strings.xml b/presentation/src/main/res/values-ru/strings.xml index 38ff9e648..5a9723f31 100644 --- a/presentation/src/main/res/values-ru/strings.xml +++ b/presentation/src/main/res/values-ru/strings.xml @@ -125,6 +125,8 @@ Запланировать сообщение Прикрепить контакт Ошибка чтения контакта + Attach audio + Attach a video Выбрана SIM-карта %1$d (%2$s) Выбрано %s, сменить SIM-карту diff --git a/presentation/src/main/res/values-sk/strings.xml b/presentation/src/main/res/values-sk/strings.xml index 1a936dc78..d234192e6 100644 --- a/presentation/src/main/res/values-sk/strings.xml +++ b/presentation/src/main/res/values-sk/strings.xml @@ -125,6 +125,8 @@ Naplánovať správu Pripojiť kontakt Chyba čítania kontaktu + Attach audio + Attach a video Vybrána SIM %1$d (%2$s) %s vybrané, zmeňte SIM kartu diff --git a/presentation/src/main/res/values-sl/strings.xml b/presentation/src/main/res/values-sl/strings.xml index feec57f00..d098e827a 100644 --- a/presentation/src/main/res/values-sl/strings.xml +++ b/presentation/src/main/res/values-sl/strings.xml @@ -125,6 +125,8 @@ Načrtuj sporočilo Vstavi stik Napaka pri branju stika + Attach audio + Attach a video SIM %1$d (%2$s) selected %s izbran, zamenjaj kartico SIM diff --git a/presentation/src/main/res/values-sr/strings.xml b/presentation/src/main/res/values-sr/strings.xml index 71abcce51..8c20a36c0 100644 --- a/presentation/src/main/res/values-sr/strings.xml +++ b/presentation/src/main/res/values-sr/strings.xml @@ -124,6 +124,8 @@ Планирај поруку Приложи контакт Грешка при учитавању контакта + Attach audio + Attach a video Изабрана SIM картица %1$d (%2$s) Изабрано: %s; промените SIM картицу diff --git a/presentation/src/main/res/values-sv/strings.xml b/presentation/src/main/res/values-sv/strings.xml index 7fdcff5ff..786c47121 100644 --- a/presentation/src/main/res/values-sv/strings.xml +++ b/presentation/src/main/res/values-sv/strings.xml @@ -123,6 +123,8 @@ Schemalägg meddelande Bifoga en kontakt Fel uppstod när kontakt lästes in + Attach audio + Attach a video SIM %1$d (%2$s) valdes %s valt, byt SIM-kort diff --git a/presentation/src/main/res/values-th/strings.xml b/presentation/src/main/res/values-th/strings.xml index 0ef07860f..4df17a91c 100644 --- a/presentation/src/main/res/values-th/strings.xml +++ b/presentation/src/main/res/values-th/strings.xml @@ -122,6 +122,8 @@ กำหนดเวลาของข้อความ Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s เลือก เปลี่ยน SIM การ์ด diff --git a/presentation/src/main/res/values-tl/strings.xml b/presentation/src/main/res/values-tl/strings.xml index 3d9821a6b..6793cca74 100644 --- a/presentation/src/main/res/values-tl/strings.xml +++ b/presentation/src/main/res/values-tl/strings.xml @@ -123,6 +123,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -247,7 +249,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS diff --git a/presentation/src/main/res/values-tr/strings.xml b/presentation/src/main/res/values-tr/strings.xml index 803093652..b07bc2937 100644 --- a/presentation/src/main/res/values-tr/strings.xml +++ b/presentation/src/main/res/values-tr/strings.xml @@ -123,6 +123,8 @@ Mesajı zamanlama Bir kişi ekle Kişi okunurken hata oluştu + Attach audio + Attach a video SIM %1$d (%2$s) seçili Seçili, %s SIM kartı değiştirin diff --git a/presentation/src/main/res/values-uk/strings.xml b/presentation/src/main/res/values-uk/strings.xml index 9403551a9..dc53d4d85 100644 --- a/presentation/src/main/res/values-uk/strings.xml +++ b/presentation/src/main/res/values-uk/strings.xml @@ -125,6 +125,8 @@ Запланувати повідомлення Прикріпити контакт Помилка читання контакту + Attach audio + Attach a video Обрана SIM-карта %1$d (%2$s) %s обрано, змініть SIM-картку diff --git a/presentation/src/main/res/values-ur/strings.xml b/presentation/src/main/res/values-ur/strings.xml index 15c5a2e7b..6ce8ff70c 100644 --- a/presentation/src/main/res/values-ur/strings.xml +++ b/presentation/src/main/res/values-ur/strings.xml @@ -123,6 +123,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -247,7 +249,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS diff --git a/presentation/src/main/res/values-vi/strings.xml b/presentation/src/main/res/values-vi/strings.xml index 2c98a28d9..ec07dc6ca 100644 --- a/presentation/src/main/res/values-vi/strings.xml +++ b/presentation/src/main/res/values-vi/strings.xml @@ -122,6 +122,8 @@ Hẹn giờ tin nhắn Đính kèm liên hệ Lỗi đọc liên hệ + Attach audio + Attach a video Đã chọn SIM %1$d (%2$s) %s đã được chọn, hãy đổi thẻ SIM diff --git a/presentation/src/main/res/values-zh-rCN/strings.xml b/presentation/src/main/res/values-zh-rCN/strings.xml index 0bf3954fd..8a8671328 100644 --- a/presentation/src/main/res/values-zh-rCN/strings.xml +++ b/presentation/src/main/res/values-zh-rCN/strings.xml @@ -122,6 +122,8 @@ 定时消息 附加联系人 读取联系人时出错 + Attach audio + Attach a video 已选择 SIM 卡 %1$d (%2$s) %s 已选择,更改 SIM 卡 diff --git a/presentation/src/main/res/values-zh/strings.xml b/presentation/src/main/res/values-zh/strings.xml index ffcd5c23e..e4c38e808 100644 --- a/presentation/src/main/res/values-zh/strings.xml +++ b/presentation/src/main/res/values-zh/strings.xml @@ -122,6 +122,8 @@ 排程訊息 附加聯絡人 讀取聯絡人時出錯 + Attach audio + Attach a video 已選取%1$d (%2$s) SIM卡 %s 已選擇,變更 SIM 卡 diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 2fe3e3301..dabd9978c 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -137,6 +137,8 @@ Schedule message Attach a contact Error reading contact + Attach audio + Attach a video SIM %1$d (%2$s) selected %s selected, change SIM card @@ -271,7 +273,7 @@ Send long messages as MMS If your longer text messages are failing to send, or sending in the wrong order, you can send them as MMS messages instead. Additional charges may apply - Auto-compress MMS attachments + Auto-compress MMS image attachments Sync messages Re-sync your messages with the native Android SMS database About QKSMS