diff --git a/CHANGELOG.md b/CHANGELOG.md index 58ab976f..3193a1ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Changelog ========== +Version 5.10.1 *(2021-09-16)* +---------------------------- + + * Automatically resize sent MMS image attachments by default, allow customizing the limit + * Added Draft support + * Allow marking conversations un/read from the main screen + * Some other stability, UX and translation improvements + Version 5.10.0 *(2021-08-27)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 0844aa10..ab02e588 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.simplemobiletools.smsmessenger" minSdkVersion 22 targetSdkVersion 30 - versionCode 35 - versionName "5.10.0" + versionCode 36 + versionName "5.10.1" setProperty("archivesBaseName", "sms-messenger") } @@ -56,7 +56,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:8979ca8187' + implementation 'com.github.SimpleMobileTools:Simple-Commons:f49f7b5f89' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'com.klinkerapps:android-smsmms:5.2.6' implementation 'com.github.tibbi:IndicatorFastScroll:c3de1d040a' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a40d3d85..ea66d25e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -195,6 +195,16 @@ + + + + () private var messages = ArrayList() private val availableSIMCards = ArrayList() - private var attachmentUris = LinkedHashSet() + private var attachmentSelections = mutableMapOf() + private val imageCompressor by lazy { ImageCompressor(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -119,7 +122,7 @@ class ThreadActivity : SimpleActivity() { override fun onPause() { super.onPause() - if (thread_type_message.value != "" && attachmentUris.isEmpty()) { + if (thread_type_message.value != "" && attachmentSelections.isEmpty()) { saveSmsDraft(thread_type_message.value, threadId) } else { deleteSmsDraft(threadId) @@ -390,7 +393,10 @@ class ThreadActivity : SimpleActivity() { private fun setupParticipants() { if (participants.isEmpty()) { participants = if (messages.isEmpty()) { - getThreadParticipants(threadId, null) + val intentNumbers = getPhoneNumbersFromIntent() + val participants = getThreadParticipants(threadId, null) + + fixParticipantNumbers(participants, intentNumbers) } else { messages.first().participants } @@ -583,7 +589,7 @@ class ThreadActivity : SimpleActivity() { conversationsDB.markRead(threadId) } - if (i == cnt - 1 && (message.type == Telephony.Sms.MESSAGE_TYPE_SENT )) { + if (i == cnt - 1 && (message.type == Telephony.Sms.MESSAGE_TYPE_SENT)) { items.add(ThreadSent(message.id, delivered = message.status == Telephony.Sms.STATUS_COMPLETE)) } } @@ -606,29 +612,57 @@ class ThreadActivity : SimpleActivity() { } private fun addAttachment(uri: Uri) { - if (attachmentUris.contains(uri)) { + val originalUriString = uri.toString() + if (attachmentSelections.containsKey(originalUriString)) { return } - attachmentUris.add(uri) + attachmentSelections[originalUriString] = AttachmentSelection(uri, false) + val attachmentView = addAttachmentView(originalUriString, uri) + val mimeType = contentResolver.getType(uri) ?: return + + if (mimeType.isImageMimeType() && config.mmsFileSizeLimit != FILE_SIZE_NONE) { + val selection = attachmentSelections[originalUriString] + attachmentSelections[originalUriString] = selection!!.copy(isPending = true) + checkSendMessageAvailability() + attachmentView.thread_attachment_progress.beVisible() + imageCompressor.compressImage(uri, config.mmsFileSizeLimit) { compressedUri -> + runOnUiThread { + if (compressedUri != null) { + attachmentSelections[originalUriString] = AttachmentSelection(compressedUri, false) + loadAttachmentPreview(attachmentView, compressedUri) + } + checkSendMessageAvailability() + attachmentView.thread_attachment_progress.beGone() + } + } + } + } + + private fun addAttachmentView(originalUri: String, uri: Uri): View { thread_attachments_holder.beVisible() val attachmentView = layoutInflater.inflate(R.layout.item_attachment, null).apply { thread_attachments_wrapper.addView(this) thread_remove_attachment.setOnClickListener { thread_attachments_wrapper.removeView(this) - attachmentUris.remove(uri) - if (attachmentUris.isEmpty()) { + attachmentSelections.remove(originalUri) + if (attachmentSelections.isEmpty()) { thread_attachments_holder.beGone() } } } + loadAttachmentPreview(attachmentView, uri) + return attachmentView + } + + private fun loadAttachmentPreview(attachmentView: View, uri: Uri) { val roundedCornersRadius = resources.getDimension(R.dimen.medium_margin).toInt() val options = RequestOptions() .diskCacheStrategy(DiskCacheStrategy.NONE) .transform(CenterCrop(), RoundedCorners(roundedCornersRadius)) - Glide.with(this) + Glide.with(attachmentView.thread_attachment_preview) .load(uri) .transition(DrawableTransitionOptions.withCrossFade()) .apply(options) @@ -650,7 +684,7 @@ class ThreadActivity : SimpleActivity() { } private fun checkSendMessageAvailability() { - if (thread_type_message.text.isNotEmpty() || attachmentUris.isNotEmpty()) { + if (thread_type_message.text.isNotEmpty() || (attachmentSelections.isNotEmpty() && !attachmentSelections.values.any { it.isPending })) { thread_send_message.isClickable = true thread_send_message.alpha = 0.9f } else { @@ -660,11 +694,13 @@ class ThreadActivity : SimpleActivity() { } private fun sendMessage() { - val msg = thread_type_message.value - if (msg.isEmpty() && attachmentUris.isEmpty()) { + var msg = thread_type_message.value + if (msg.isEmpty() && attachmentSelections.isEmpty()) { return } + msg = removeDiacriticsIfNeeded(msg) + val numbers = ArrayList() participants.forEach { it.phoneNumbers.forEach { @@ -687,11 +723,11 @@ class ThreadActivity : SimpleActivity() { val transaction = Transaction(this, settings) val message = com.klinker.android.send_message.Message(msg, numbers.toTypedArray()) - if (attachmentUris.isNotEmpty()) { - for (uri in attachmentUris) { + if (attachmentSelections.isNotEmpty()) { + for (selection in attachmentSelections.values) { try { - val byteArray = contentResolver.openInputStream(uri)?.readBytes() ?: continue - val mimeType = contentResolver.getType(uri) ?: continue + val byteArray = contentResolver.openInputStream(selection.uri)?.readBytes() ?: continue + val mimeType = contentResolver.getType(selection.uri) ?: continue message.addMedia(byteArray, mimeType) } catch (e: Exception) { showErrorToast(e) @@ -711,7 +747,7 @@ class ThreadActivity : SimpleActivity() { refreshedSinceSent = false transaction.sendNewMessage(message, threadId) thread_type_message.setText("") - attachmentUris.clear() + attachmentSelections.clear() thread_attachments_holder.beGone() thread_attachments_wrapper.removeAllViews() @@ -781,6 +817,41 @@ class ThreadActivity : SimpleActivity() { showSelectedContacts() } + private fun getPhoneNumbersFromIntent(): ArrayList { + val numberFromIntent = intent.getStringExtra(THREAD_NUMBER) + val numbers = ArrayList() + + if (numberFromIntent != null) { + if (numberFromIntent.startsWith('[') && numberFromIntent.endsWith(']')) { + val type = object : TypeToken>() {}.type + numbers.addAll(Gson().fromJson(numberFromIntent, type)) + } else { + numbers.add(numberFromIntent) + } + } + return numbers + } + + private fun fixParticipantNumbers(participants: ArrayList, properNumbers: ArrayList): ArrayList { + for (number in properNumbers) { + for (participant in participants) { + participant.phoneNumbers = participant.phoneNumbers.map { + val numberWithoutPlus = number.replace("+", "") + if (numberWithoutPlus == it.trim()) { + if (participant.name == it) { + participant.name = number + } + number + } else { + it + } + } as ArrayList + } + } + + return participants + } + @SuppressLint("MissingPermission") @Subscribe(threadMode = ThreadMode.ASYNC) fun refreshMessages(event: Events.RefreshMessages) { diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt index 2990622a..cbccb4b1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt @@ -217,6 +217,11 @@ class ConversationsAdapter( conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach { activity.markThreadMessagesUnread(it.threadId) } + + activity.runOnUiThread { + refreshMessages() + finishActMode() + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt new file mode 100644 index 00000000..c55bbe7b --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Bitmap.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.smsmessenger.extensions + +import android.graphics.Bitmap + +fun Bitmap.CompressFormat.extension() = when (this) { + Bitmap.CompressFormat.PNG -> "png" + Bitmap.CompressFormat.WEBP -> "webp" + else -> "jpg" +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt index 1e2479d0..a4c845db 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt @@ -5,6 +5,7 @@ import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent +import android.content.ContentResolver import android.content.ContentValues import android.content.Context import android.content.Intent @@ -17,6 +18,7 @@ import android.net.Uri import android.os.Handler import android.os.Looper import android.provider.ContactsContract.PhoneLookup +import android.provider.OpenableColumns import android.provider.Telephony.* import android.text.TextUtils import androidx.core.app.NotificationCompat @@ -35,8 +37,10 @@ import com.simplemobiletools.smsmessenger.interfaces.MessagesDao import com.simplemobiletools.smsmessenger.models.* import com.simplemobiletools.smsmessenger.receivers.DirectReplyReceiver import com.simplemobiletools.smsmessenger.receivers.MarkAsReadReceiver +import java.io.FileNotFoundException import java.util.* import kotlin.collections.ArrayList +import java.text.Normalizer import me.leolin.shortcutbadger.ShortcutBadger val Context.config: Config get() = Config.newInstance(applicationContext) @@ -73,11 +77,7 @@ fun Context.getMessages(threadId: Long): ArrayList { val blockedNumbers = getBlockedNumbers() var messages = ArrayList() queryCursor(uri, projection, selection, selectionArgs, sortOrder, showErrors = true) { cursor -> - val senderNumber = cursor.getStringValue(Sms.ADDRESS) - - if(senderNumber == null){ - return@queryCursor - } + val senderNumber = cursor.getStringValue(Sms.ADDRESS) ?: return@queryCursor val isNumberBlocked = if (blockStatus.containsKey(senderNumber)) { blockStatus[senderNumber]!! @@ -783,6 +783,10 @@ fun Context.getLockScreenVisibilityText(type: Int) = getString( } ) +fun Context.removeDiacriticsIfNeeded(text: String): String { + return if (config.useSimpleCharacters) text.normalizeString() else text +} + fun Context.getSmsDraft(threadId: Long): String? { val uri = Sms.Draft.CONTENT_URI val projection = arrayOf(Sms.BODY) @@ -835,6 +839,18 @@ fun Context.deleteSmsDraft(threadId: Long) { } } +fun Context.getMMSFileLimitText(size: Long) = getString( + when (size) { + FILE_SIZE_100_KB -> R.string.mms_file_size_limit_100kb + FILE_SIZE_200_KB -> R.string.mms_file_size_limit_200kb + FILE_SIZE_300_KB -> R.string.mms_file_size_limit_300kb + FILE_SIZE_600_KB -> R.string.mms_file_size_limit_600kb + FILE_SIZE_1_MB -> R.string.mms_file_size_limit_1mb + FILE_SIZE_2_MB -> R.string.mms_file_size_limit_2mb + else -> R.string.mms_file_size_limit_none + } +) + fun Context.updateLastConversationMessage(threadId: Long) { val uri = Threads.CONTENT_URI val selection = "${Threads._ID} = ?" @@ -846,3 +862,38 @@ fun Context.updateLastConversationMessage(threadId: Long) { } catch (e: Exception) { } } + +fun Context.getFileSizeFromUri(uri: Uri): Long { + val assetFileDescriptor = try { + contentResolver.openAssetFileDescriptor(uri, "r") + } catch (e: FileNotFoundException) { + null + } + + // uses ParcelFileDescriptor#getStatSize underneath if failed + val length = assetFileDescriptor?.use { it.length } ?: FILE_SIZE_NONE + if (length != -1L) { + return length + } + + // if "content://" uri scheme, try contentResolver table + if (uri.scheme.equals(ContentResolver.SCHEME_CONTENT)) { + return contentResolver.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null) + ?.use { cursor -> + // maybe shouldn't trust ContentResolver for size: + // https://stackoverflow.com/questions/48302972/content-resolver-returns-wrong-size + val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) + if (sizeIndex == -1) { + return@use FILE_SIZE_NONE + } + cursor.moveToFirst() + return try { + cursor.getLong(sizeIndex) + } catch (_: Throwable) { + FILE_SIZE_NONE + } + } ?: FILE_SIZE_NONE + } else { + return FILE_SIZE_NONE + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/String.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/String.kt new file mode 100644 index 00000000..acdf0bb9 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/String.kt @@ -0,0 +1,16 @@ +package com.simplemobiletools.smsmessenger.extensions + +fun String.getExtensionFromMimeType(): String { + return when (lowercase()) { + "image/png" -> ".png" + "image/apng" -> ".apng" + "image/webp" -> ".webp" + "image/svg+xml" -> ".svg" + "image/gif" -> ".gif" + else -> ".jpg" + } +} + +fun String.isImageMimeType(): Boolean { + return lowercase().startsWith("image") +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt index 8b590b0e..c6e5c601 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt @@ -18,6 +18,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(SHOW_CHARACTER_COUNTER, false) set(showCharacterCounter) = prefs.edit().putBoolean(SHOW_CHARACTER_COUNTER, showCharacterCounter).apply() + var useSimpleCharacters: Boolean + get() = prefs.getBoolean(USE_SIMPLE_CHARACTERS, false) + set(useSimpleCharacters) = prefs.edit().putBoolean(USE_SIMPLE_CHARACTERS, useSimpleCharacters).apply() + var enableDeliveryReports: Boolean get() = prefs.getBoolean(ENABLE_DELIVERY_REPORTS, true) set(enableDeliveryReports) = prefs.edit().putBoolean(ENABLE_DELIVERY_REPORTS, enableDeliveryReports).apply() @@ -26,6 +30,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getInt(LOCK_SCREEN_VISIBILITY, LOCK_SCREEN_SENDER_MESSAGE) set(lockScreenVisibilitySetting) = prefs.edit().putInt(LOCK_SCREEN_VISIBILITY, lockScreenVisibilitySetting).apply() + var mmsFileSizeLimit: Long + get() = prefs.getLong(MMS_FILE_SIZE_LIMIT, FILE_SIZE_1_MB) + set(mmsFileSizeLimit) = prefs.edit().putLong(MMS_FILE_SIZE_LIMIT, mmsFileSizeLimit).apply() + var lastExportPath: String get() = prefs.getString(LAST_EXPORT_PATH, "")!! set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt index 7e99610e..9e74d87c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -13,8 +13,10 @@ const val SEARCHED_MESSAGE_ID = "searched_message_id" const val USE_SIM_ID_PREFIX = "use_sim_id_" const val NOTIFICATION_CHANNEL = "simple_sms_messenger" const val SHOW_CHARACTER_COUNTER = "show_character_counter" +const val USE_SIMPLE_CHARACTERS = "use_simple_characters" const val LOCK_SCREEN_VISIBILITY = "lock_screen_visibility" const val ENABLE_DELIVERY_REPORTS = "enable_delivery_reports" +const val MMS_FILE_SIZE_LIMIT = "mms_file_size_limit" const val LAST_EXPORT_PATH = "last_export_path" const val EXPORT_SMS = "export_sms" const val EXPORT_MMS = "export_mms" @@ -40,6 +42,14 @@ const val LOCK_SCREEN_SENDER_MESSAGE = 1 const val LOCK_SCREEN_SENDER = 2 const val LOCK_SCREEN_NOTHING = 3 +const val FILE_SIZE_NONE = -1L +const val FILE_SIZE_100_KB = 102_400L +const val FILE_SIZE_200_KB = 204_800L +const val FILE_SIZE_300_KB = 307_200L +const val FILE_SIZE_600_KB = 614_400L +const val FILE_SIZE_1_MB = 1_048_576L +const val FILE_SIZE_2_MB = 2_097_152L + fun refreshMessages() { EventBus.getDefault().post(Events.RefreshMessages()) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt new file mode 100644 index 00000000..aa58387e --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/ImageCompressor.kt @@ -0,0 +1,119 @@ +package com.simplemobiletools.smsmessenger.helpers + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Matrix +import android.media.ExifInterface +import android.net.Uri +import com.simplemobiletools.commons.extensions.getCompressionFormat +import com.simplemobiletools.commons.extensions.getMyFileUri +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.smsmessenger.extensions.extension +import com.simplemobiletools.smsmessenger.extensions.getExtensionFromMimeType +import com.simplemobiletools.smsmessenger.extensions.getFileSizeFromUri +import com.simplemobiletools.smsmessenger.extensions.isImageMimeType +import java.io.File +import java.io.FileOutputStream + +/** + * Compress image to a given size based on + * [Compressor](https://github.com/zetbaitsu/Compressor/) + * */ +class ImageCompressor(private val context: Context) { + private val contentResolver = context.contentResolver + private val outputDirectory = File(context.cacheDir, "compressed").apply { + if (!exists()) { + mkdirs() + } + } + + fun compressImage(uri: Uri, compressSize: Long, callback: (compressedFileUri: Uri?) -> Unit) { + ensureBackgroundThread { + try { + val fileSize = context.getFileSizeFromUri(uri) + if (fileSize > compressSize) { + val mimeType = contentResolver.getType(uri)!! + if (mimeType.isImageMimeType()) { + val byteArray = contentResolver.openInputStream(uri)?.readBytes()!! + var destinationFile = File(outputDirectory, System.currentTimeMillis().toString().plus(mimeType.getExtensionFromMimeType())) + destinationFile.writeBytes(byteArray) + val constraint = SizeConstraint(compressSize) + while (constraint.isSatisfied(destinationFile).not()) { + destinationFile = constraint.satisfy(destinationFile) + } + callback.invoke(context.getMyFileUri(destinationFile)) + } else { + callback.invoke(null) + } + } else { + //no need to compress since the file is less than the compress size + callback.invoke(uri) + } + } catch (e: Exception) { + callback.invoke(null) + } + } + } + + private fun overWrite(imageFile: File, bitmap: Bitmap, format: Bitmap.CompressFormat = imageFile.path.getCompressionFormat(), quality: Int = 100): File { + val result = if (format == imageFile.path.getCompressionFormat()) { + imageFile + } else { + File("${imageFile.absolutePath.substringBeforeLast(".")}.${format.extension()}") + } + imageFile.delete() + saveBitmap(bitmap, result, format, quality) + return result + } + + private fun saveBitmap(bitmap: Bitmap, destination: File, format: Bitmap.CompressFormat = destination.path.getCompressionFormat(), quality: Int = 100) { + destination.parentFile?.mkdirs() + var fileOutputStream: FileOutputStream? = null + try { + fileOutputStream = FileOutputStream(destination.absolutePath) + bitmap.compress(format, quality, fileOutputStream) + } finally { + fileOutputStream?.run { + flush() + close() + } + } + } + + private fun loadBitmap(imageFile: File) = BitmapFactory.decodeFile(imageFile.absolutePath).run { + determineImageRotation(imageFile, this) + } + + private fun determineImageRotation(imageFile: File, bitmap: Bitmap): Bitmap { + val exif = ExifInterface(imageFile.absolutePath) + val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0) + val matrix = Matrix() + when (orientation) { + 6 -> matrix.postRotate(90f) + 3 -> matrix.postRotate(180f) + 8 -> matrix.postRotate(270f) + } + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + } + + private inner class SizeConstraint( + private val maxFileSize: Long, + private val stepSize: Int = 10, + private val maxIteration: Int = 10, + private val minQuality: Int = 10 + ) { + private var iteration: Int = 0 + + fun isSatisfied(imageFile: File): Boolean { + return imageFile.length() <= maxFileSize || iteration >= maxIteration + } + + fun satisfy(imageFile: File): File { + iteration++ + val quality = (100 - iteration * stepSize).takeIf { it >= minQuality } ?: minQuality + return overWrite(imageFile, loadBitmap(imageFile), quality = quality) + } + } + +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt new file mode 100644 index 00000000..e56835d2 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/AttachmentSelection.kt @@ -0,0 +1,8 @@ +package com.simplemobiletools.smsmessenger.models + +import android.net.Uri + +data class AttachmentSelection( + val uri: Uri, + val isPending: Boolean, +) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt index 8a4ee30c..79e333b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/DirectReplyReceiver.kt @@ -11,6 +11,7 @@ import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.smsmessenger.extensions.conversationsDB import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead +import com.simplemobiletools.smsmessenger.extensions.removeDiacriticsIfNeeded import com.simplemobiletools.smsmessenger.helpers.REPLY import com.simplemobiletools.smsmessenger.helpers.THREAD_ID import com.simplemobiletools.smsmessenger.helpers.THREAD_NUMBER @@ -19,7 +20,9 @@ class DirectReplyReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val address = intent.getStringExtra(THREAD_NUMBER) val threadId = intent.getLongExtra(THREAD_ID, 0L) - val msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return + var msg = RemoteInput.getResultsFromIntent(intent).getCharSequence(REPLY)?.toString() ?: return + + msg = context.removeDiacriticsIfNeeded(msg) val settings = Settings() settings.useSystemSending = true diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt index 4525f30d..5488c3aa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/MarkAsReadReceiver.kt @@ -10,6 +10,7 @@ import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead import com.simplemobiletools.smsmessenger.extensions.updateUnreadCountBadge import com.simplemobiletools.smsmessenger.helpers.MARK_AS_READ import com.simplemobiletools.smsmessenger.helpers.THREAD_ID +import com.simplemobiletools.smsmessenger.helpers.refreshMessages class MarkAsReadReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -21,6 +22,7 @@ class MarkAsReadReceiver : BroadcastReceiver() { context.markThreadMessagesRead(threadId) context.conversationsDB.markRead(threadId) context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations()) + refreshMessages() } } } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 859fdf00..77283b63 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -195,6 +195,29 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_attachment.xml b/app/src/main/res/layout/item_attachment.xml index ee25d173..be794651 100644 --- a/app/src/main/res/layout/item_attachment.xml +++ b/app/src/main/res/layout/item_attachment.xml @@ -1,14 +1,24 @@ + android:layout_width="@dimen/attachment_preview_size" + android:layout_height="@dimen/attachment_preview_size"> + android:visibility="gone" + tools:visibility="visible" /> + + + android:visibility="gone" + tools:visibility="visible" /> diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 37651ec0..af8271c5 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Proč aplikace vyžaduje přístup k internetu? diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index d9067fb0..16102277 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Hvorfor kræver appen adgang til internettet? diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d7e5e614..40f69e22 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Warum benötigt diese App Internetzugriff? diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 73901649..ec01e170 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -49,6 +49,9 @@ Αποστολέας και μήνυμα Αποστολέας μόνο Ενεργοποίηση αναφορών παράδοσης + Αφαίρεση τονισμών και διακριτικών κατά την αποστολή μηνυμάτων + Αλλαγή μεγέθους απεσταλμένων εικόνων MMS + Χωρίς όριο Γιατί η εφαρμογή απαιτεί πρόσβαση στο Internet; diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0f2ec0f6..a267726e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit ¿Por qué la aplicación requiere acceso a internet? diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 3f6b221f..ab3a4416 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Miksi sovellus vaatii Internet-yhteyden? diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index acf8de23..1625d4fd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -2,21 +2,21 @@ Simple SMS Messenger SMS Messenger Écrivez un message… - Message not sent - Not sent. Touch to retry. - Your message to \'%s\' has not been sent + Message non envoyé + Pas envoyé. Appuyez pour réessayer. + Votre message à \'%s\' n\'a pas été envoyé Ajouter une personne Pièce jointe Aucune conversation enregistrée n\'a été trouvée Commencer une conversation Répondre - Show a character counter at writing messages - Loading messages… - Sender doesn\'t support replies - Draft - Sending… - Export messages - Import messages + Afficher le nombre de caractères lors de l\'écriture de messages + Chargement des messages… + L\'expéditeur n\'accepte pas les réponses + Brouillon + Envoi en cours… + Export de messages + Import de messages Nouvelle conversation @@ -45,15 +45,18 @@ - Lock screen notification visibility - Sender and message - Sender only - Enable delivery reports + Visibilité des notifications sur l\'écran de verrouillage + Expéditeur et message + Expéditeur uniquement + Activer les rapports d\'envoi + Supprimer les accents et caractères spéciaux lors de l\'envoi de messages + Redimensionner les images MMS envoyées + Pas de limite Pourquoi cette application a besoin d\'un accès à internet ? Malheureusement, cela est nécessaire pour envoyer des pièces jointes dans les MMS. Ne pas pouvoir envoyer de MMS serait un énorme désavantage comparé à d\'autres applications, nous avons donc décidé de faire ainsi. - Cependant, comme toujours, il n\'y a aucune publicité, traqueur ou analyseur de quelque sorte, internet n\'est utilisé que pour envoyer des MMS. + Cependant, comme toujours, il n\'y a aucune publicité, traqueur ou analyseur de quelque sorte, internet n\'est utilisé que pour envoyer des MMS. diff --git a/app/src/main/res/values-gl b/app/src/main/res/values-gl/strings.xml similarity index 75% rename from app/src/main/res/values-gl rename to app/src/main/res/values-gl/strings.xml index ef3cabd1..d566febf 100644 --- a/app/src/main/res/values-gl +++ b/app/src/main/res/values-gl/strings.xml @@ -2,12 +2,21 @@ Simple SMS Messenger Mensaxe SMS Escribir unha mensaxe… - Mensaxe non enviada + Mensaxe non enviada + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Engadir persoa Anexo Non se atoparon conversas Iniciar unha conversa Responder + Show a character counter at writing messages + Loading messages… + Sender doesn\'t support replies + Draft + Sending… + Export messages + Import messages Nova conversa @@ -35,6 +44,15 @@ %d mensaxes + + Lock screen notification visibility + Sender and message + Sender only + Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit + Por que o aplicativo necesita acceder a Internet? Infelizmente é a única forma para poder enviar anexos MMS. A incapacidade de non conseguir enviar MMS sería unha enorme desvantaxe comparativamente a outros aplicativos e, por iso, tomamos esta decisión. Pero, como habitualmente, o aplicativo non ten anuncios, non rastrea os utilizadores nin recolle datos persoais. Este permiso só é necesario para enviar as MMS. diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 0db16d26..e4217469 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Mengapa aplikasi membutuhkan akses ke internet? diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index b6201852..b1477e50 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -49,6 +49,9 @@ Mittente e messaggio Solo mittente Abilita conferma di consegna + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Perché l\'applicazione richiede l\'accesso ad internet? diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8c5071ec..b281ca3d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit なぜアプリ使用にインターネットへのアクセスが必要なのですか? diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index ea039ad8..714051b0 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Why does the app require access to the internet? diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 366149ef..50c2029f 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit അപ്ലിക്കേഷന് ഇന്റർനെറ്റിലേക്ക് ആവശ്യമായി വരുന്നത് എന്തുകൊണ്ട്? diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 0f9e313a..759d3c56 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -49,6 +49,9 @@ Afzender en bericht Alleen afzender Bezorgingsrapporten inschakelen + Accenten en diakritische tekens verwijderen bij het verzenden van berichten + Afbeelding verkleinen voor MMS + Geen limiet Waarom heeft deze app toegang nodig tot het internet? diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 7bc60f8a..bd91ca19 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -51,6 +51,9 @@ Nadawca i treść Tylko nadawca Włącz raporty doręczeń + Usuwaj akcenty i znaki diakrytyczne podczas wysyłania wiadomości + Rozmiar wysyłanych obrazków w MMS-ach + Bez limitu Dlaczego aplikacja wymaga dostępu do Internetu? diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index f6cf255b..4f08f40e 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Porque é que a aplicação necessita de aceder à Internet? diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f6944577..c4ae0a0b 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -51,6 +51,9 @@ Отправитель и сообщение Только отправитель Использовать отчёты о доставке + Удалять ударения и диакритические знаки при отправке сообщений + Изменять размер отправляемых в MMS изображений + Нет ограничения Почему приложение требует доступ к интернету? diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index f1092bb8..5c922a60 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -12,7 +12,7 @@ Odpovedať Zobraziť počítadlo znakov pri písaní správ Načítanie správ… - Sender doesn\'t support replies + Odosielateľ nepodporuje odpovede Koncept Odosiela sa… Exportovať správy @@ -51,6 +51,9 @@ Odosielateľ a správa Iba odosielateľ Povoliť správy o doručení + Odstrániť diakritiku pri odosielaní správ + Zmenšiť MMS obrázky pri odosielaní + Žiadny limit Prečo vyžaduje apka prístup na internet? diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index f7a3224e..575b3c20 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Uygulama neden internete erişim gerektiriyor? diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index b0a239d0..8a5a6b46 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Чому додаток потрубує доступу до інтернету? diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b6542e07..c2622ff6 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -49,6 +49,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit 为什么该应用需要访问互联网? diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 24f6140e..244c41e4 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -2,4 +2,11 @@ com.simplemobiletools.smsmessenger + 100KB + 200KB + 300KB + 600KB + 1MB + 2MB + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 527171ed..a4ac6ad8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,6 +47,9 @@ Sender and message Sender only Enable delivery reports + Remove accents and diacritics at sending messages + Resize sent MMS images + No limit Messages diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 00000000..d2c19fcd --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,4 @@ + + + + diff --git a/build.gradle b/build.gradle index 22e54ea7..b2370fda 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.5.21' + ext.kotlin_version = '1.5.30' repositories { google() jcenter() diff --git a/fastlane/metadata/android/en-US/changelogs/36.txt b/fastlane/metadata/android/en-US/changelogs/36.txt new file mode 100644 index 00000000..a60f0002 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/36.txt @@ -0,0 +1,4 @@ + * Automatically resize sent MMS image attachments by default, allow customizing the limit + * Added Draft support + * Allow marking conversations un/read from the main screen + * Some other stability, UX and translation improvements