diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt index c4ab1ac6..b1a072b9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt @@ -257,9 +257,14 @@ class MainActivity : SimpleActivity() { } cachedConversations.forEach { cachedConv -> - val conv = conversations.find { it.threadId == cachedConv.threadId && !Conversation.areContentsTheSame(cachedConv, it) } + val conv = conversations.find { + it.threadId == cachedConv.threadId && !Conversation.areContentsTheSame(cachedConv, it) + } if (conv != null) { - val conversation = conv.copy(date = maxOf(cachedConv.date, conv.date)) + val lastModified = maxOf(cachedConv.date, conv.date) + val usesCustomTitle = cachedConv.usesCustomTitle + val title = if (usesCustomTitle) cachedConv.title else conv.title + val conversation = conv.copy(date = lastModified, title = title, usesCustomTitle = usesCustomTitle) conversationsDB.insertOrUpdate(conversation) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt index f1a9d0d2..67f9be0f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt @@ -51,6 +51,7 @@ import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.adapters.AttachmentsAdapter import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter +import com.simplemobiletools.smsmessenger.dialogs.RenameConversationDialog import com.simplemobiletools.smsmessenger.dialogs.ScheduleMessageDialog import com.simplemobiletools.smsmessenger.extensions.* import com.simplemobiletools.smsmessenger.helpers.* @@ -80,6 +81,7 @@ class ThreadActivity : SimpleActivity() { private var refreshedSinceSent = false private var threadItems = ArrayList() private var bus: EventBus? = null + private var conversation: Conversation? = null private var participants = ArrayList() private var privateContacts = ArrayList() private var messages = ArrayList() @@ -120,6 +122,7 @@ class ThreadActivity : SimpleActivity() { handlePermission(PERMISSION_READ_PHONE_STATE) { granted -> if (granted) { setupButtons() + setupConversation() setupCachedMessages { val searchedMessageId = intent.getLongExtra(SEARCHED_MESSAGE_ID, -1L) intent.removeExtra(SEARCHED_MESSAGE_ID) @@ -184,6 +187,7 @@ class ThreadActivity : SimpleActivity() { val firstPhoneNumber = participants.firstOrNull()?.phoneNumbers?.firstOrNull()?.value thread_toolbar.menu.apply { findItem(R.id.delete).isVisible = threadItems.isNotEmpty() + findItem(R.id.rename_conversation).isVisible = participants.size > 1 && conversation != null findItem(R.id.block_number).title = addLockedLabelIfNeeded(R.string.block_number) findItem(R.id.block_number).isVisible = isNougatPlus() findItem(R.id.dial_number).isVisible = participants.size == 1 @@ -205,6 +209,7 @@ class ThreadActivity : SimpleActivity() { when (menuItem.itemId) { R.id.block_number -> tryBlocking() R.id.delete -> askConfirmDelete() + R.id.rename_conversation -> renameConversation() R.id.add_number_to_contact -> addNumberToContact() R.id.dial_number -> dialNumber() R.id.manage_people -> managePeople() @@ -485,6 +490,12 @@ class ThreadActivity : SimpleActivity() { } } + private fun setupConversation() { + ensureBackgroundThread { + conversation = conversationsDB.getConversationWithThreadId(threadId) + } + } + private fun setupButtons() { updateTextColors(thread_holder) val textColor = getProperTextColor() @@ -638,9 +649,11 @@ class ThreadActivity : SimpleActivity() { } private fun setupThreadTitle() { - val threadTitle = participants.getThreadTitle() - if (threadTitle.isNotEmpty()) { - thread_toolbar.title = participants.getThreadTitle() + val title = conversation?.title + thread_toolbar.title = if (!title.isNullOrEmpty()) { + title + } else { + participants.getThreadTitle() } } @@ -827,6 +840,17 @@ class ThreadActivity : SimpleActivity() { } } + private fun renameConversation() { + RenameConversationDialog(this, conversation!!) { title -> + ensureBackgroundThread { + conversation = renameConversation(conversation!!, newTitle = title) + runOnUiThread { + setupThreadTitle() + } + } + } + } + @SuppressLint("MissingPermission") private fun getThreadItems(): ArrayList { val items = ArrayList() 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 880d96dc..28a25a64 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt @@ -24,6 +24,7 @@ import com.simplemobiletools.commons.helpers.isNougatPlus import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity +import com.simplemobiletools.smsmessenger.dialogs.RenameConversationDialog import com.simplemobiletools.smsmessenger.extensions.* import com.simplemobiletools.smsmessenger.helpers.refreshMessages import com.simplemobiletools.smsmessenger.models.Conversation @@ -60,6 +61,7 @@ class ConversationsAdapter( findItem(R.id.cab_add_number_to_contact).isVisible = isOneItemSelected() && selectedItems.firstOrNull()?.isGroupConversation == false findItem(R.id.cab_dial_number).isVisible = isOneItemSelected() && selectedItems.firstOrNull()?.isGroupConversation == false findItem(R.id.cab_copy_number).isVisible = isOneItemSelected() && selectedItems.firstOrNull()?.isGroupConversation == false + findItem(R.id.rename_conversation).isVisible = isOneItemSelected() && selectedItems.firstOrNull()?.isGroupConversation == true findItem(R.id.cab_mark_as_read).isVisible = selectedItems.any { !it.read } findItem(R.id.cab_mark_as_unread).isVisible = selectedItems.any { it.read } checkPinBtnVisibility(this) @@ -77,6 +79,7 @@ class ConversationsAdapter( R.id.cab_dial_number -> dialNumber() R.id.cab_copy_number -> copyNumberToClipboard() R.id.cab_delete -> askConfirmDelete() + R.id.rename_conversation -> renameConversation(getSelectedItems().first()) R.id.cab_mark_as_read -> markAsRead() R.id.cab_mark_as_unread -> markAsUnread() R.id.cab_pin_conversation -> pinConversation(true) @@ -211,6 +214,21 @@ class ConversationsAdapter( } } + private fun renameConversation(conversation: Conversation) { + RenameConversationDialog(activity, conversation) { + ensureBackgroundThread { + val updatedConv = activity.renameConversation(conversation, newTitle = it) + activity.runOnUiThread { + finishActMode() + currentList.toMutableList().apply { + set(indexOf(conversation), updatedConv) + updateConversations(this as ArrayList) + } + } + } + } + } + private fun markAsRead() { if (selectedKeys.isEmpty()) { return @@ -222,10 +240,7 @@ class ConversationsAdapter( activity.markThreadMessagesRead(it.threadId) } - activity.runOnUiThread { - refreshMessages() - finishActMode() - } + refreshConversations() } } @@ -240,10 +255,7 @@ class ConversationsAdapter( activity.markThreadMessagesUnread(it.threadId) } - activity.runOnUiThread { - refreshMessages() - finishActMode() - } + refreshConversations() } } @@ -271,10 +283,7 @@ class ConversationsAdapter( activity.config.removePinnedConversations(conversations) } - activity.runOnUiThread { - refreshMessages() - finishActMode() - } + refreshConversations() } private fun checkPinBtnVisibility(menu: Menu) { @@ -364,6 +373,13 @@ class ConversationsAdapter( override fun onChange(position: Int) = currentList.getOrNull(position)?.title ?: "" + private fun refreshConversations() { + activity.runOnUiThread { + refreshMessages() + finishActMode() + } + } + private fun saveRecyclerViewState() { recyclerViewState = recyclerView.layoutManager?.onSaveInstanceState() } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/databases/MessagesDatabase.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/databases/MessagesDatabase.kt index 72fda67f..030d6be6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/databases/MessagesDatabase.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/databases/MessagesDatabase.kt @@ -17,7 +17,7 @@ import com.simplemobiletools.smsmessenger.models.Conversation import com.simplemobiletools.smsmessenger.models.Message import com.simplemobiletools.smsmessenger.models.MessageAttachment -@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 5) +@Database(entities = [Conversation::class, Attachment::class, MessageAttachment::class, Message::class], version = 6) @TypeConverters(Converters::class) abstract class MessagesDatabase : RoomDatabase() { @@ -42,6 +42,7 @@ abstract class MessagesDatabase : RoomDatabase() { .addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_4_5) + .addMigrations(MIGRATION_5_6) .build() } } @@ -97,5 +98,13 @@ abstract class MessagesDatabase : RoomDatabase() { } } } + + private val MIGRATION_5_6 = object : Migration(5, 6) { + override fun migrate(database: SupportSQLiteDatabase) { + database.apply { + execSQL("ALTER TABLE conversations ADD COLUMN uses_custom_title INTEGER NOT NULL DEFAULT 0") + } + } + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/RenameConversationDialog.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/RenameConversationDialog.kt new file mode 100644 index 00000000..f5f8af71 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/dialogs/RenameConversationDialog.kt @@ -0,0 +1,62 @@ +package com.simplemobiletools.smsmessenger.dialogs + +import android.app.Activity +import android.content.DialogInterface.BUTTON_POSITIVE +import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog +import androidx.core.widget.doAfterTextChanged +import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.smsmessenger.R +import com.simplemobiletools.smsmessenger.models.Conversation +import kotlinx.android.synthetic.main.dialog_rename_conversation.view.* + +class RenameConversationDialog( + private val activity: Activity, + private val conversation: Conversation, + private val callback: (name: String) -> Unit, +) { + + private var dialog: AlertDialog? = null + + init { + val textColor = activity.getProperTextColor() + val primaryColor = activity.getProperPrimaryColor() + val backgroundColor = activity.getProperBackgroundColor() + + val view = (activity.layoutInflater.inflate(R.layout.dialog_rename_conversation, null) as ViewGroup).apply { + rename_conv_input_layout.apply { + setColors(textColor, primaryColor, backgroundColor) + setBoxCornerRadiiResources(R.dimen.medium_margin, R.dimen.medium_margin, R.dimen.medium_margin, R.dimen.medium_margin) + } + rename_conv_edit_text.apply { + setTextColor(textColor) + if (conversation.usesCustomTitle) { + setText(conversation.title) + } + hint = conversation.title + + doAfterTextChanged { + dialog?.getButton(BUTTON_POSITIVE)?.isEnabled = !it.isNullOrEmpty() + } + } + } + + activity.getAlertDialogBuilder() + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.cancel, null) + .apply { + activity.setupDialogStuff(view, this, R.string.rename_conversation) { alertDialog -> + dialog = alertDialog + alertDialog.showKeyboard(view.rename_conv_edit_text) + alertDialog.getButton(BUTTON_POSITIVE).apply { + val newTitle = view.rename_conv_edit_text.text.toString() + isEnabled = newTitle.isNotEmpty() && (newTitle != conversation.title) + setOnClickListener { + alertDialog.dismiss() + callback(view.rename_conv_edit_text.text.toString()) + } + } + } + } + } +} 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 28190c1f..0d7c2c52 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt @@ -1023,6 +1023,20 @@ fun Context.subscriptionManagerCompat(): SubscriptionManager { } } +fun Context.renameConversation(conversation: Conversation, newTitle: String): Conversation { + require(conversation.isGroupConversation) { + "Can only rename group conversations." + } + + val updatedConv = conversation.copy(title = newTitle, usesCustomTitle = true) + try { + conversationsDB.insertOrUpdate(updatedConv) + } catch (e: Exception) { + e.printStackTrace() + } + return updatedConv +} + fun Context.createTemporaryThread(message: Message, threadId: Long = generateRandomId()) { val simpleContactHelper = SimpleContactsHelper(this) val addresses = message.participants.getAddresses() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Conversation.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Conversation.kt index 5da76a0f..c20d376c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Conversation.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/models/Conversation.kt @@ -15,7 +15,8 @@ data class Conversation( @ColumnInfo(name = "photo_uri") var photoUri: String, @ColumnInfo(name = "is_group_conversation") var isGroupConversation: Boolean, @ColumnInfo(name = "phone_number") var phoneNumber: String, - @ColumnInfo(name = "is_scheduled") var isScheduled: Boolean = false + @ColumnInfo(name = "is_scheduled") var isScheduled: Boolean = false, + @ColumnInfo(name = "uses_custom_title") var usesCustomTitle: Boolean = false ) { companion object { diff --git a/app/src/main/res/layout/dialog_rename_conversation.xml b/app/src/main/res/layout/dialog_rename_conversation.xml new file mode 100644 index 00000000..3016e39e --- /dev/null +++ b/app/src/main/res/layout/dialog_rename_conversation.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/menu/cab_conversations.xml b/app/src/main/res/menu/cab_conversations.xml index 6560bd24..410223ea 100644 --- a/app/src/main/res/menu/cab_conversations.xml +++ b/app/src/main/res/menu/cab_conversations.xml @@ -28,6 +28,11 @@ android:showAsAction="never" android:title="@string/copy_number_to_clipboard" app:showAsAction="never" /> + +