diff --git a/CHANGELOG.md b/CHANGELOG.md index dd67cdce..6830fd49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Changelog ========== +Version 5.8.0 *(2021-01-02)* +---------------------------- + + * Improved delivery reports, show a notification at failed messages + * Allow resending failed messages with tapping them + * Added multiple dual-SIM related improvements + * Many other UX, stability, performance and translation improvements + Version 5.7.0 *(2020-12-30)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 2d71ade9..91ee3631 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId "com.simplemobiletools.smsmessenger" minSdkVersion 22 targetSdkVersion 30 - versionCode 23 - versionName "5.7.0" + versionCode 25 + versionName "5.8.0" setProperty("archivesBaseName", "sms-messenger") } @@ -56,7 +56,7 @@ android { } dependencies { - implementation 'com.simplemobiletools:commons:5.32.19' + implementation 'com.simplemobiletools:commons:5.32.20' implementation 'org.greenrobot:eventbus:3.2.0' implementation 'com.klinkerapps:android-smsmms:5.2.6' implementation 'com.github.tibbi:IndicatorFastScroll:08f512858a' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 814fde4a..2e542b99 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -121,6 +121,10 @@ + + + + @@ -149,11 +153,6 @@ android:exported="true" android:taskAffinity="com.klinker.android.messaging.MMS_RECEIVED" /> - - () private var bus: EventBus? = null private var participants = ArrayList() @@ -219,8 +224,18 @@ class ThreadActivity : SimpleActivity() { invalidateOptionsMenu() runOnUiThread { - val adapter = ThreadAdapter(this, threadItems, thread_messages_list, thread_messages_fastscroller) {} - thread_messages_list.adapter = adapter + val currAdapter = thread_messages_list.adapter + if (currAdapter == null) { + ThreadAdapter(this, threadItems, thread_messages_list, thread_messages_fastscroller) { + (it as? ThreadError)?.apply { + thread_type_message.setText(it.messageText) + } + }.apply { + thread_messages_list.adapter = this + } + } else { + (currAdapter as ThreadAdapter).updateMessages(threadItems) + } } SimpleContactsHelper(this).getAvailableContacts(false) { contacts -> @@ -509,7 +524,11 @@ class ThreadActivity : SimpleActivity() { items.add(message) if (message.type == Telephony.Sms.MESSAGE_TYPE_FAILED) { - items.add(ThreadError(message.id)) + items.add(ThreadError(message.id, message.body)) + } + + if (message.type == Telephony.Sms.MESSAGE_TYPE_OUTBOX) { + items.add(ThreadSending(message.id)) } if (!message.read) { @@ -637,12 +656,24 @@ class ThreadActivity : SimpleActivity() { } try { - transaction.sendNewMessage(message, threadId) + val smsSentIntent = Intent(this, SmsStatusSentReceiver::class.java) + val deliveredIntent = Intent(this, SmsStatusDeliveredReceiver::class.java) + transaction.setExplicitBroadcastForSentSms(smsSentIntent) + transaction.setExplicitBroadcastForDeliveredSms(deliveredIntent) + + refreshedSinceSent = false + transaction.sendNewMessage(message, threadId) thread_type_message.setText("") attachmentUris.clear() thread_attachments_holder.beGone() thread_attachments_wrapper.removeAllViews() + + Handler().postDelayed({ + if (!refreshedSinceSent) { + refreshMessages() + } + }, 2000) } catch (e: Exception) { showErrorToast(e) } catch (e: Error) { @@ -704,8 +735,10 @@ class ThreadActivity : SimpleActivity() { showSelectedContacts() } + @SuppressLint("MissingPermission") @Subscribe(threadMode = ThreadMode.ASYNC) fun refreshMessages(event: Events.RefreshMessages) { + refreshedSinceSent = true if (isActivityVisible) { notificationManager.cancel(threadId.hashCode()) } @@ -713,8 +746,17 @@ class ThreadActivity : SimpleActivity() { val lastMaxId = messages.maxByOrNull { it.id }?.id ?: 0L messages = getMessages(threadId) - messages.filter { !it.isReceivedMessage() && it.id > lastMaxId }.forEach { - messagesDB.insertOrIgnore(it) + messages.filter { !it.isReceivedMessage() && it.id > lastMaxId }.forEach { latestMessage -> + // subscriptionIds seem to be not filled out at sending with multiple SIM cards, so fill it manually + if (SubscriptionManager.from(this).activeSubscriptionInfoList?.size ?: 0 > 1) { + val SIMId = availableSIMCards.getOrNull(currentSIMCardIndex)?.subscriptionId + if (SIMId != null) { + updateMessageSubscriptionId(latestMessage.id, SIMId) + latestMessage.subscriptionId = SIMId + } + } + + messagesDB.insertOrIgnore(latestMessage) } setupAdapter() 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 83e5814f..8b1de0ca 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt @@ -56,6 +56,7 @@ class ConversationsAdapter(activity: SimpleActivity, var conversations: ArrayLis R.id.cab_dial_number -> dialNumber() R.id.cab_copy_number -> copyNumberToClipboard() R.id.cab_delete -> askConfirmDelete() + R.id.cab_select_all -> selectAll() } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt index fe750b20..8c6ae60b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt @@ -39,6 +39,7 @@ import kotlinx.android.synthetic.main.item_received_unknown_attachment.view.* import kotlinx.android.synthetic.main.item_sent_unknown_attachment.view.* import kotlinx.android.synthetic.main.item_thread_date_time.view.* import kotlinx.android.synthetic.main.item_thread_error.view.* +import kotlinx.android.synthetic.main.item_thread_sending.view.* import kotlinx.android.synthetic.main.item_thread_success.view.* class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList, recyclerView: MyRecyclerView, fastScroller: FastScroller, @@ -74,6 +75,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList shareText() R.id.cab_select_text -> selectText() R.id.cab_delete -> askConfirmDelete() + R.id.cab_select_all -> selectAll() } } @@ -95,6 +97,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList R.layout.item_received_message THREAD_SENT_MESSAGE_ERROR -> R.layout.item_thread_error THREAD_SENT_MESSAGE_SUCCESS -> R.layout.item_thread_success + THREAD_SENT_MESSAGE_SENDING -> R.layout.item_thread_sending else -> R.layout.item_sent_message } return createViewHolder(layout, parent) @@ -102,11 +105,14 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList + val isClickable = item is ThreadError || item is Message + val isLongClickable = item is Message + holder.bindView(item, isClickable, isLongClickable) { itemView, layoutPosition -> when (item) { is ThreadDateTime -> setupDateTime(itemView, item) is ThreadSuccess -> setupThreadSuccess(itemView) is ThreadError -> setupThreadError(itemView) + is ThreadSending -> setupThreadSending(itemView) else -> setupView(itemView, item as Message) } } @@ -122,6 +128,7 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList THREAD_RECEIVED_MESSAGE item is ThreadError -> THREAD_SENT_MESSAGE_ERROR item is ThreadSuccess -> THREAD_SENT_MESSAGE_SUCCESS + item is ThreadSending -> THREAD_SENT_MESSAGE_SENDING else -> THREAD_SENT_MESSAGE } } @@ -190,10 +197,13 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList) { + val oldHashCode = messages.hashCode() + val newHashCode = newMessages.hashCode() + if (newHashCode != oldHashCode) { + messages = newMessages + notifyDataSetChanged() + recyclerView.scrollToPosition(messages.size - 1) } } @@ -256,7 +266,9 @@ class ThreadAdapter(activity: SimpleActivity, var messages: ArrayList?): ArrayList { val uri = Uri.parse("${MmsSms.CONTENT_CONVERSATIONS_URI}?simple=true") val projection = arrayOf( @@ -554,6 +577,26 @@ fun Context.markThreadMessagesUnread(threadId: Long) { } } +fun Context.updateMessageType(id: Long, status: Int) { + val uri = Sms.CONTENT_URI + val contentValues = ContentValues().apply { + put(Sms.TYPE, status) + } + val selection = "${Sms._ID} = ?" + val selectionArgs = arrayOf(id.toString()) + contentResolver.update(uri, contentValues, selection, selectionArgs) +} + +fun Context.updateMessageSubscriptionId(messageId: Long, subscriptionId: Int) { + val uri = Sms.CONTENT_URI + val contentValues = ContentValues().apply { + put(Sms.SUBSCRIPTION_ID, subscriptionId) + } + val selection = "${Sms._ID} = ?" + val selectionArgs = arrayOf(messageId.toString()) + contentResolver.update(uri, contentValues, selection, selectionArgs) +} + fun Context.updateUnreadCountBadge(conversations: List) { val unreadCount = conversations.count { !it.read } if (unreadCount == 0) { @@ -592,18 +635,23 @@ fun Context.getThreadId(addresses: Set): Long { fun Context.showReceivedMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?) { val privateCursor = getMyContactsCursor()?.loadInBackground() ensureBackgroundThread { - var sender = getNameAndPhotoFromPhoneNumber(address).name - if (address == sender) { - val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor) - sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address - } + val senderName = getNameFromAddress(address, privateCursor) Handler(Looper.getMainLooper()).post { - showMessageNotification(address, body, threadId, bitmap, sender) + showMessageNotification(address, body, threadId, bitmap, senderName) } } } +fun Context.getNameFromAddress(address: String, privateCursor: Cursor?): String { + var sender = getNameAndPhotoFromPhoneNumber(address).name + if (address == sender) { + val privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor) + sender = privateContacts.firstOrNull { it.doesContainPhoneNumber(address) }?.name ?: address + } + return sender +} + @SuppressLint("NewApi") fun Context.showMessageNotification(address: String, body: String, threadId: Long, bitmap: Bitmap?, sender: String) { val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 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 d4190f1a..1705773f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -23,6 +23,7 @@ const val THREAD_RECEIVED_MESSAGE = 2 const val THREAD_SENT_MESSAGE = 3 const val THREAD_SENT_MESSAGE_ERROR = 4 const val THREAD_SENT_MESSAGE_SUCCESS = 5 +const val THREAD_SENT_MESSAGE_SENDING = 6 fun refreshMessages() { EventBus.getDefault().post(Events.RefreshMessages()) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt index 629c3dfa..c3dc8d71 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/interfaces/MessagesDao.kt @@ -29,6 +29,9 @@ interface MessagesDao { @Query("UPDATE messages SET read = 1 WHERE thread_id = :threadId") fun markThreadRead(threadId: Long) + @Query("UPDATE messages SET type = :type WHERE id = :id") + fun updateType(id: Long, type: Int): Int + @Query("DELETE FROM messages WHERE id = :id") fun delete(id: Long) diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Message.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Message.kt index a9580099..54d96d04 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Message.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Message.kt @@ -19,7 +19,7 @@ data class Message( @ColumnInfo(name = "attachment") val attachment: MessageAttachment?, @ColumnInfo(name = "sender_name") var senderName: String, @ColumnInfo(name = "sender_photo_uri") val senderPhotoUri: String, - @ColumnInfo(name = "subscription_id") val subscriptionId: Int) : ThreadItem() { + @ColumnInfo(name = "subscription_id") var subscriptionId: Int) : ThreadItem() { fun isReceivedMessage() = type == Telephony.Sms.MESSAGE_TYPE_INBOX } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadError.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadError.kt index 9b0f003e..9e32530d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadError.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadError.kt @@ -1,3 +1,3 @@ package com.simplemobiletools.smsmessenger.models -data class ThreadError(val messageID: Long) : ThreadItem() +data class ThreadError(val messageId: Long, val messageText: String) : ThreadItem() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadSending.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadSending.kt new file mode 100644 index 00000000..131f7386 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/ThreadSending.kt @@ -0,0 +1,3 @@ +package com.simplemobiletools.smsmessenger.models + +data class ThreadSending(val messageId: Long) : ThreadItem() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt index 2a613685..cc2efb88 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsReceiver.kt @@ -44,7 +44,8 @@ class SmsReceiver : BroadcastReceiver() { context.updateUnreadCountBadge(context.conversationsDB.getUnreadConversations()) val participant = SimpleContact(0, 0, address, "", arrayListOf(address), ArrayList(), ArrayList()) - val message = Message(newMessageId, body, type, arrayListOf(participant), (date / 1000).toInt(), false, threadId, false, null, address, "", subscriptionId) + val message = Message(newMessageId, body, type, arrayListOf(participant), (date / 1000).toInt(), false, threadId, + false, null, address, "", subscriptionId) context.messagesDB.insertOrUpdate(message) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsSentReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsSentReceiver.kt deleted file mode 100644 index 2321c414..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsSentReceiver.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.simplemobiletools.smsmessenger.receivers - -import android.content.Context -import android.content.Intent -import com.klinker.android.send_message.SentReceiver -import com.simplemobiletools.smsmessenger.helpers.refreshMessages - -class SmsSentReceiver : SentReceiver() { - override fun onMessageStatusUpdated(context: Context, intent: Intent, receiverResultCode: Int) { - refreshMessages() - } -} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt new file mode 100644 index 00000000..b7aa5593 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusDeliveredReceiver.kt @@ -0,0 +1,37 @@ +package com.simplemobiletools.smsmessenger.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Handler +import android.os.Looper +import android.provider.Telephony +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.smsmessenger.extensions.messagesDB +import com.simplemobiletools.smsmessenger.extensions.updateMessageType +import com.simplemobiletools.smsmessenger.helpers.refreshMessages + +class SmsStatusDeliveredReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + if (intent.extras?.containsKey("message_uri") == true) { + val uri = Uri.parse(intent.getStringExtra("message_uri")) + val messageId = uri?.lastPathSegment?.toLong() ?: 0L + ensureBackgroundThread { + val type = Telephony.Sms.MESSAGE_TYPE_SENT + context.updateMessageType(messageId, type) + val updated = context.messagesDB.updateType(messageId, type) + if (updated == 0) { + Handler(Looper.getMainLooper()).postDelayed({ + ensureBackgroundThread { + context.messagesDB.updateType(messageId, type) + } + }, 2000) + } + + refreshMessages() + } + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt new file mode 100644 index 00000000..6f7451f6 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/receivers/SmsStatusSentReceiver.kt @@ -0,0 +1,109 @@ +package com.simplemobiletools.smsmessenger.receivers + +import android.annotation.SuppressLint +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.media.AudioAttributes +import android.media.AudioManager +import android.media.RingtoneManager +import android.net.Uri +import android.os.Handler +import android.os.Looper +import android.provider.Telephony +import androidx.core.app.NotificationCompat +import com.simplemobiletools.commons.extensions.getMyContactsCursor +import com.simplemobiletools.commons.helpers.SimpleContactsHelper +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.helpers.isOreoPlus +import com.simplemobiletools.smsmessenger.R +import com.simplemobiletools.smsmessenger.activities.ThreadActivity +import com.simplemobiletools.smsmessenger.extensions.* +import com.simplemobiletools.smsmessenger.helpers.NOTIFICATION_CHANNEL +import com.simplemobiletools.smsmessenger.helpers.THREAD_ID +import com.simplemobiletools.smsmessenger.helpers.refreshMessages + +class SmsStatusSentReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + if (intent.extras?.containsKey("message_uri") == true) { + val uri = Uri.parse(intent.getStringExtra("message_uri")) + val messageId = uri?.lastPathSegment?.toLong() ?: 0L + ensureBackgroundThread { + val type = if (intent.extras!!.containsKey("errorCode")) { + showSendingFailedNotification(context, messageId) + Telephony.Sms.MESSAGE_TYPE_FAILED + } else { + Telephony.Sms.MESSAGE_TYPE_OUTBOX + } + context.updateMessageType(messageId, type) + context.messagesDB.updateType(messageId, type) + refreshMessages() + } + } + } + + private fun showSendingFailedNotification(context: Context, messageId: Long) { + Handler(Looper.getMainLooper()).post { + val privateCursor = context.getMyContactsCursor()?.loadInBackground() + ensureBackgroundThread { + val address = context.getMessageRecipientAddress(messageId) + val threadId = context.getThreadId(address) + val senderName = context.getNameFromAddress(address, privateCursor) + showNotification(context, senderName, threadId) + } + } + } + + @SuppressLint("NewApi") + private fun showNotification(context: Context, recipientName: String, threadId: Long) { + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + if (isOreoPlus()) { + val audioAttributes = AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setLegacyStreamType(AudioManager.STREAM_NOTIFICATION) + .build() + + val name = context.getString(R.string.message_not_sent_short) + val importance = NotificationManager.IMPORTANCE_HIGH + NotificationChannel(NOTIFICATION_CHANNEL, name, importance).apply { + setBypassDnd(false) + enableLights(true) + setSound(soundUri, audioAttributes) + enableVibration(true) + notificationManager.createNotificationChannel(this) + } + } + + val intent = Intent(context, ThreadActivity::class.java).apply { + putExtra(THREAD_ID, threadId) + } + + val pendingIntent = PendingIntent.getActivity(context, threadId.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT) + val summaryText = String.format(context.getString(R.string.message_sending_error), recipientName) + + val largeIcon = SimpleContactsHelper(context).getContactLetterIcon(recipientName) + val builder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL) + .setContentTitle(context.getString(R.string.message_not_sent_short)) + .setContentText(summaryText) + .setColor(context.config.primaryColor) + .setSmallIcon(R.drawable.ic_messenger) + .setLargeIcon(largeIcon) + .setStyle(NotificationCompat.BigTextStyle().bigText(summaryText)) + .setContentIntent(pendingIntent) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setDefaults(Notification.DEFAULT_LIGHTS) + .setCategory(Notification.CATEGORY_MESSAGE) + .setAutoCancel(true) + .setSound(soundUri, AudioManager.STREAM_NOTIFICATION) + .setChannelId(NOTIFICATION_CHANNEL) + + notificationManager.notify(threadId.hashCode(), builder.build()) + } +} diff --git a/app/src/main/res/layout/activity_new_conversation.xml b/app/src/main/res/layout/activity_new_conversation.xml index f76e807f..aaf95c05 100644 --- a/app/src/main/res/layout/activity_new_conversation.xml +++ b/app/src/main/res/layout/activity_new_conversation.xml @@ -42,7 +42,7 @@ android:id="@+id/no_contacts_placeholder" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_below="@+id/message_divider_two" + android:layout_below="@+id/suggestions_scrollview" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/bigger_margin" android:alpha="0.8" diff --git a/app/src/main/res/layout/item_thread_error.xml b/app/src/main/res/layout/item_thread_error.xml index 6fb425d8..344769c4 100644 --- a/app/src/main/res/layout/item_thread_error.xml +++ b/app/src/main/res/layout/item_thread_error.xml @@ -6,6 +6,6 @@ android:gravity="end" android:paddingStart="@dimen/activity_margin" android:paddingEnd="@dimen/activity_margin" - android:text="@string/message_not_sent" + android:text="@string/message_not_sent_touch_retry" android:textColor="@color/theme_dark_red_primary_color" android:textSize="@dimen/normal_text_size" /> diff --git a/app/src/main/res/layout/item_thread_sending.xml b/app/src/main/res/layout/item_thread_sending.xml new file mode 100644 index 00000000..b89f4f6a --- /dev/null +++ b/app/src/main/res/layout/item_thread_sending.xml @@ -0,0 +1,10 @@ + + diff --git a/app/src/main/res/menu/cab_conversations.xml b/app/src/main/res/menu/cab_conversations.xml index 113b5be4..19f7a611 100644 --- a/app/src/main/res/menu/cab_conversations.xml +++ b/app/src/main/res/menu/cab_conversations.xml @@ -25,4 +25,8 @@ android:id="@+id/cab_copy_number" android:title="@string/copy_number_to_clipboard" app:showAsAction="never" /> + diff --git a/app/src/main/res/menu/cab_thread.xml b/app/src/main/res/menu/cab_thread.xml index e78aef8f..ed5b8a85 100644 --- a/app/src/main/res/menu/cab_thread.xml +++ b/app/src/main/res/menu/cab_thread.xml @@ -20,4 +20,8 @@ android:icon="@drawable/ic_delete_vector" android:title="@string/delete" app:showAsAction="ifRoom" /> + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 520c5be2..a861ccd0 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -2,7 +2,9 @@ Schlichter SMS Messenger SMS Messenger Schreibe eine Nachricht… - Nachricht wurde nicht gesendet. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Person hinzufügen Anhang Keine gespeicherten Chats gefunden diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 1132b47a..b6f10a90 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -2,7 +2,9 @@ Απλός SMS Messenger SMS Messenger Πληκτρολογήστε ένα μήνυμα… - Το μήνυμα δεν έχει σταλεί. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Προσθήκη ατόμου Συνημμένο Δεν βρέθηκαν αποθηκευμένες συνομιλίες diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3066aa3e..3516f9ed 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -2,7 +2,9 @@ Mensajería SMS Simple Mensajería SMS Escribe un mensaje… - El mensaje no se ha enviado. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Añadir persona Archivo adjunto No se han encontrado conversaciones diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 552ff722..b418260b 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger SMS Messenger Écrivez un message… - Le message n\'a pas été envoyé. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Ajouter une personne Pièce jointe Aucune conversation enregistrée n\'a été trouvée diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index b7e12b7c..df73b0b3 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger SMS Messenger Ketik pesan… - Pesan belum terkirim. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Tambahkan Orang Lampiran Tidak ada percakapan tersimpan yang ditemukan diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index df1b2f23..356e1f19 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -2,7 +2,9 @@ Simple ショートメール ショートメール メッセージを入力してください… - 送信されませんでした。 + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent 宛先を追加 添付 保存された会話はありません diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index c02ca2a3..1d10f2cf 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -2,7 +2,9 @@ Paprastas SMS Siuntiklis SMS Siuntiklis Rašykite žinutę… - Žinutė neišsiųsta. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Pridėti žmogų Priedas Nebuvo rasta išsaugotų pokalbių diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 5f4eb165..4eafaf66 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger SMS മെസഞ്ചർ മെസ്സേജ് ടൈപ്പ് ചെയ്യുക - മെസ്സേജ് അയച്ചിട്ടില്ല. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent വ്യക്തിയെ ചേർക്കുക അറ്റാച്ചുമെന്റ് സ്റ്റോർ ചെയ്ത സംഭാഷണങ്ങളൊന്നും കണ്ടെത്തിയില്ല diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index f5e7e0a9..3d8ef86c 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -2,7 +2,9 @@ Eenvoudig Berichtenbeheer (SMS) Berichten Typ een bericht… - Bericht niet verzonden. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Persoon toevoegen Bijlage Geen opgeslagen berichten gevonden @@ -10,9 +12,9 @@ Beantwoorden Teller voor het aantal tekens weergeven Berichten laden… - Sender doesn\'t support replies - Draft - Sending… + Afzender ondersteunt geen antwoorden + Concept + Versturen… Nieuw gesprek diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c263baf6..a2c51645 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger SMS Messenger Escrever uma mensagem… - Mensagem não enviada + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Adicionar pessoa Anexo Não foram encontradas conversas diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 513550b8..b41f8a74 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger Сообщения Введите сообщение… - Сообщение не отправлено. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Добавить участника Вложение Нет сохранённых переписок diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 89cc373b..54a8271f 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -2,7 +2,9 @@ Jednoduché SMS správy SMS správy Zadajte správu… - Správa nebola odoslaná. + Správa nebola odoslaná + Správa neodoslaná. Dotykom to skúste znova. + Vaša správa pre \'%s\' nebola odoslaná Pridať osobu Príloha Nenašli sa žiadne uložené konverzácie diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 9e42b548..3f55992f 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -2,7 +2,9 @@ Basit SMS Messenger SMS Messenger Bir mesaj yazın… - Mesaj gönderilmedi. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Kişi Ekle Ek Kaydedilmiş görüşme bulunamadı diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 3b23c2c4..338bb279 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger Повідомлення Введіть повідомлення… - Повідомлення не надіслано. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Додати учасник а Вкладення Немає збережених листувань diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 50d5077c..2abf8998 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -2,7 +2,9 @@ 简易短信 短信 输入一个消息… - 消息尚未发送。 + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent 添加人 附件 未找到保存的对话 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 444dd7f8..c40c26d6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,7 +2,9 @@ Simple SMS Messenger SMS Messenger Type a message… - Message has not been sent. + Message not sent + Not sent. Touch to retry. + Your message to \'%s\' has not been sent Add Person Attachment No stored conversations have been found diff --git a/fastlane/metadata/android/en-US/changelogs/25.txt b/fastlane/metadata/android/en-US/changelogs/25.txt new file mode 100644 index 00000000..dcb4ce35 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/25.txt @@ -0,0 +1,4 @@ + * Improved delivery reports, show a notification at failed messages + * Allow resending failed messages with tapping them + * Added multiple dual-SIM related improvements + * Many other UX, stability, performance and translation improvements