Clear drafts instead of deleting them

Closes https://github.com/FossifyOrg/Messages/issues/13
This commit is contained in:
Naveen Singh 2025-01-04 03:23:59 +05:30
parent 4434d187bc
commit f343085703
No known key found for this signature in database
GPG key ID: AF5D43C216778C0B
3 changed files with 65 additions and 45 deletions

View file

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

View file

@ -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<Conversation>(activity, recyclerView, ConversationDiffCallback(), itemClick, onRefresh),
activity: SimpleActivity,
recyclerView: MyRecyclerView,
onRefresh: () -> Unit,
itemClick: (Any) -> Unit
) : MyRecyclerViewListAdapter<Conversation>(
activity,
recyclerView,
ConversationDiffCallback(),
itemClick,
onRefresh
),
RecyclerViewFastScroller.OnPopupTextUpdate {
private var fontSize = activity.getTextSize()
private var drafts = HashMap<Long, String?>()
private var drafts = HashMap<Long, String>()
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<Conversation>, commitCallback: (() -> Unit)? = null) {
fun updateConversations(
newConversations: ArrayList<Conversation>,
commitCallback: (() -> Unit)? = null
) {
saveRecyclerViewState()
submitList(newConversations.toList(), commitCallback)
}
@SuppressLint("NotifyDataSetChanged")
fun updateDrafts() {
ensureBackgroundThread {
val newDrafts = HashMap<Long, String?>()
val newDrafts = HashMap<Long, String>()
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<Conversation>
protected fun getSelectedItems() =
currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
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<Long, String?>) {
private fun fetchDrafts(drafts: HashMap<Long, String>) {
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
)
}
}

View file

@ -1064,8 +1064,8 @@ fun Context.getSmsDraft(threadId: Long): String? {
return null
}
fun Context.getAllDrafts(): HashMap<Long, String?> {
val drafts = HashMap<Long, String?>()
fun Context.getAllDrafts(): HashMap<Long, String> {
val drafts = HashMap<Long, String>()
val uri = Sms.Draft.CONTENT_URI
val projection = arrayOf(Sms.BODY, Sms.THREAD_ID)
@ -1075,20 +1075,19 @@ fun Context.getAllDrafts(): HashMap<Long, String?> {
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))
}