Add ability to rename group conversations

This commit is contained in:
Naveen 2022-11-21 02:51:51 +05:30
parent 75bbd5ea0e
commit 8d283858e1
10 changed files with 201 additions and 19 deletions

View File

@ -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)
}
}

View File

@ -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<ThreadItem>()
private var bus: EventBus? = null
private var conversation: Conversation? = null
private var participants = ArrayList<SimpleContact>()
private var privateContacts = ArrayList<SimpleContact>()
private var messages = ArrayList<Message>()
@ -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<ThreadItem> {
val items = ArrayList<ThreadItem>()

View File

@ -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<Conversation>)
}
}
}
}
}
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()
}

View File

@ -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")
}
}
}
}
}

View File

@ -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())
}
}
}
}
}
}

View File

@ -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()

View File

@ -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 {

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="@dimen/big_margin">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/rename_conv_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/big_margin"
android:paddingHorizontal="@dimen/tiny_margin"
android:text="@string/rename_conversation_warning"
app:layout_constraintBottom_toTopOf="@id/rename_conv_input_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.simplemobiletools.commons.views.MyTextInputLayout
android:id="@+id/rename_conv_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/big_margin"
android:layout_marginTop="@dimen/activity_margin"
android:hint="@string/conversation_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rename_conv_info">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/rename_conv_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLength="30"
android:maxLines="1" />
</com.simplemobiletools.commons.views.MyTextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -28,6 +28,11 @@
android:showAsAction="never"
android:title="@string/copy_number_to_clipboard"
app:showAsAction="never" />
<item
android:id="@+id/rename_conversation"
android:icon="@drawable/ic_edit_vector"
android:title="@string/rename_conversation"
app:showAsAction="ifRoom" />
<item
android:id="@+id/cab_mark_as_read"
android:showAsAction="never"

View File

@ -18,6 +18,11 @@
android:icon="@drawable/ic_add_person_vector"
android:title="@string/add_person"
app:showAsAction="always" />
<item
android:id="@+id/rename_conversation"
android:icon="@drawable/ic_edit_vector"
android:title="@string/rename_conversation"
app:showAsAction="ifRoom" />
<item
android:id="@+id/add_number_to_contact"
android:title="@string/add_number_to_contact"