From f34308570379f16a04ef3677f78f922df98dd53a Mon Sep 17 00:00:00 2001 From: Naveen Singh Date: Sat, 4 Jan 2025 03:23:59 +0530 Subject: [PATCH] Clear drafts instead of deleting them Closes https://github.com/FossifyOrg/Messages/issues/13 --- .../messages/activities/ThreadActivity.kt | 25 +++++--- .../adapters/BaseConversationsAdapter.kt | 58 ++++++++++++++----- .../fossify/messages/extensions/Context.kt | 27 ++------- 3 files changed, 65 insertions(+), 45 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/messages/activities/ThreadActivity.kt b/app/src/main/kotlin/org/fossify/messages/activities/ThreadActivity.kt index 3893fa7d..9fc740de 100644 --- a/app/src/main/kotlin/org/fossify/messages/activities/ThreadActivity.kt +++ b/app/src/main/kotlin/org/fossify/messages/activities/ThreadActivity.kt @@ -117,7 +117,6 @@ import org.fossify.messages.extensions.createTemporaryThread import org.fossify.messages.extensions.deleteConversation import org.fossify.messages.extensions.deleteMessage import org.fossify.messages.extensions.deleteScheduledMessage -import org.fossify.messages.extensions.deleteSmsDraft import org.fossify.messages.extensions.dialNumber import org.fossify.messages.extensions.emptyMessagesRecycleBinForConversation import org.fossify.messages.extensions.getAddresses @@ -282,7 +281,7 @@ class ThreadActivity : SimpleActivity() { ) val smsDraft = getSmsDraft(threadId) - if (smsDraft != null) { + if (!smsDraft.isNullOrEmpty()) { binding.messageHolder.threadTypeMessage.setText(smsDraft) } isActivityVisible = true @@ -307,17 +306,16 @@ class ThreadActivity : SimpleActivity() { override fun onPause() { super.onPause() - val draftMessage = binding.messageHolder.threadTypeMessage.value - if (draftMessage.isNotEmpty() && getAttachmentSelections().isEmpty()) { - saveSmsDraft(draftMessage, threadId) - } else { - deleteSmsDraft(threadId) - } - + saveDraftMessage() bus?.post(Events.RefreshMessages()) isActivityVisible = false } + override fun onStop() { + super.onStop() + saveDraftMessage() + } + override fun onBackPressed() { isAttachmentPickerVisible = false if (binding.messageHolder.attachmentPickerHolder.isVisible()) { @@ -332,6 +330,15 @@ class ThreadActivity : SimpleActivity() { bus?.unregister(this) } + private fun saveDraftMessage() { + val draftMessage = binding.messageHolder.threadTypeMessage.value + if (getAttachmentSelections().isEmpty()) { + saveSmsDraft(draftMessage, threadId) + } else { + saveSmsDraft("", threadId) + } + } + private fun refreshMenuItems() { val firstPhoneNumber = participants.firstOrNull()?.phoneNumbers?.firstOrNull()?.value val archiveAvailable = config.isArchiveAvailable diff --git a/app/src/main/kotlin/org/fossify/messages/adapters/BaseConversationsAdapter.kt b/app/src/main/kotlin/org/fossify/messages/adapters/BaseConversationsAdapter.kt index ac064d68..d6ea2d81 100644 --- a/app/src/main/kotlin/org/fossify/messages/adapters/BaseConversationsAdapter.kt +++ b/app/src/main/kotlin/org/fossify/messages/adapters/BaseConversationsAdapter.kt @@ -1,5 +1,6 @@ package org.fossify.messages.adapters +import android.annotation.SuppressLint import android.graphics.Typeface import android.os.Parcelable import android.util.TypedValue @@ -10,7 +11,11 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller import org.fossify.commons.adapters.MyRecyclerViewListAdapter -import org.fossify.commons.extensions.* +import org.fossify.commons.extensions.applyColorFilter +import org.fossify.commons.extensions.beVisibleIf +import org.fossify.commons.extensions.formatDateOrTime +import org.fossify.commons.extensions.getTextSize +import org.fossify.commons.extensions.setupViewBackground import org.fossify.commons.helpers.SimpleContactsHelper import org.fossify.commons.helpers.ensureBackgroundThread import org.fossify.commons.views.MyRecyclerView @@ -22,11 +27,20 @@ import org.fossify.messages.models.Conversation @Suppress("LeakingThis") abstract class BaseConversationsAdapter( - activity: SimpleActivity, recyclerView: MyRecyclerView, onRefresh: () -> Unit, itemClick: (Any) -> Unit -) : MyRecyclerViewListAdapter(activity, recyclerView, ConversationDiffCallback(), itemClick, onRefresh), + activity: SimpleActivity, + recyclerView: MyRecyclerView, + onRefresh: () -> Unit, + itemClick: (Any) -> Unit +) : MyRecyclerViewListAdapter( + activity, + recyclerView, + ConversationDiffCallback(), + itemClick, + onRefresh +), RecyclerViewFastScroller.OnPopupTextUpdate { private var fontSize = activity.getTextSize() - private var drafts = HashMap() + private var drafts = HashMap() private var recyclerViewState: Parcelable? = null @@ -39,24 +53,32 @@ abstract class BaseConversationsAdapter( registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { override fun onChanged() = restoreRecyclerViewState() - override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) = restoreRecyclerViewState() - override fun onItemRangeInserted(positionStart: Int, itemCount: Int) = restoreRecyclerViewState() + override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) = + restoreRecyclerViewState() + + override fun onItemRangeInserted(positionStart: Int, itemCount: Int) = + restoreRecyclerViewState() }) } + @SuppressLint("NotifyDataSetChanged") fun updateFontSize() { fontSize = activity.getTextSize() notifyDataSetChanged() } - fun updateConversations(newConversations: ArrayList, commitCallback: (() -> Unit)? = null) { + fun updateConversations( + newConversations: ArrayList, + commitCallback: (() -> Unit)? = null + ) { saveRecyclerViewState() submitList(newConversations.toList(), commitCallback) } + @SuppressLint("NotifyDataSetChanged") fun updateDrafts() { ensureBackgroundThread { - val newDrafts = HashMap() + val newDrafts = HashMap() fetchDrafts(newDrafts) if (drafts.hashCode() != newDrafts.hashCode()) { drafts = newDrafts @@ -69,7 +91,8 @@ abstract class BaseConversationsAdapter( override fun getSelectableItemCount() = itemCount - protected fun getSelectedItems() = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList + protected fun getSelectedItems() = + currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList override fun getIsItemSelectable(position: Int) = true @@ -88,7 +111,11 @@ abstract class BaseConversationsAdapter( override fun onBindViewHolder(holder: ViewHolder, position: Int) { val conversation = getItem(position) - holder.bindView(conversation, allowSingleClick = true, allowLongClick = true) { itemView, _ -> + holder.bindView( + conversation, + allowSingleClick = true, + allowLongClick = true + ) { itemView, _ -> setupView(itemView, conversation) } bindViewHolder(holder) @@ -104,7 +131,7 @@ abstract class BaseConversationsAdapter( } } - private fun fetchDrafts(drafts: HashMap) { + private fun fetchDrafts(drafts: HashMap) { drafts.clear() for ((threadId, draft) in activity.getAllDrafts()) { drafts[threadId] = draft @@ -115,7 +142,7 @@ abstract class BaseConversationsAdapter( ItemConversationBinding.bind(view).apply { root.setupViewBackground(activity) val smsDraft = drafts[conversation.threadId] - draftIndicator.beVisibleIf(smsDraft != null) + draftIndicator.beVisibleIf(!smsDraft.isNullOrEmpty()) draftIndicator.setTextColor(properPrimaryColor) pinIndicator.beVisibleIf(activity.config.pinnedConversations.contains(conversation.threadId.toString())) @@ -160,7 +187,12 @@ abstract class BaseConversationsAdapter( null } - SimpleContactsHelper(activity).loadContactImage(conversation.photoUri, conversationImage, conversation.title, placeholder) + SimpleContactsHelper(activity).loadContactImage( + conversation.photoUri, + conversationImage, + conversation.title, + placeholder + ) } } diff --git a/app/src/main/kotlin/org/fossify/messages/extensions/Context.kt b/app/src/main/kotlin/org/fossify/messages/extensions/Context.kt index c5511b75..aa1734b6 100644 --- a/app/src/main/kotlin/org/fossify/messages/extensions/Context.kt +++ b/app/src/main/kotlin/org/fossify/messages/extensions/Context.kt @@ -1064,8 +1064,8 @@ fun Context.getSmsDraft(threadId: Long): String? { return null } -fun Context.getAllDrafts(): HashMap { - val drafts = HashMap() +fun Context.getAllDrafts(): HashMap { + val drafts = HashMap() val uri = Sms.Draft.CONTENT_URI val projection = arrayOf(Sms.BODY, Sms.THREAD_ID) @@ -1075,20 +1075,19 @@ fun Context.getAllDrafts(): HashMap { while (it.moveToNext()) { val threadId = it.getLongValue(Sms.THREAD_ID) val draft = it.getStringValue(Sms.BODY) - if (draft != null) { + if (!draft.isNullOrEmpty()) { drafts[threadId] = draft } } } } catch (e: Exception) { + e.printStackTrace() } return drafts } fun Context.saveSmsDraft(body: String, threadId: Long) { - deleteSmsDraft(threadId) - val uri = Sms.Draft.CONTENT_URI val contentValues = ContentValues().apply { put(Sms.BODY, body) @@ -1104,24 +1103,6 @@ fun Context.saveSmsDraft(body: String, threadId: Long) { } } -fun Context.deleteSmsDraft(threadId: Long) { - val uri = Sms.Draft.CONTENT_URI - val projection = arrayOf(Sms._ID) - val selection = "${Sms.THREAD_ID} = ?" - val selectionArgs = arrayOf(threadId.toString()) - queryCursor( - uri = uri, - projection = projection, - selection = selection, - selectionArgs = selectionArgs, - showErrors = true - ) { cursor -> - val draftId = cursor.getLongValue(Sms._ID) - val draftUri = Uri.withAppendedPath(Sms.CONTENT_URI, "/${draftId}") - contentResolver.delete(draftUri, null, null) - } -} - fun Context.updateLastConversationMessage(threadId: Long) { updateLastConversationMessage(setOf(threadId)) }