Clear drafts instead of deleting them
Closes https://github.com/FossifyOrg/Messages/issues/13
This commit is contained in:
parent
4434d187bc
commit
f343085703
3 changed files with 65 additions and 45 deletions
|
|
@ -117,7 +117,6 @@ import org.fossify.messages.extensions.createTemporaryThread
|
||||||
import org.fossify.messages.extensions.deleteConversation
|
import org.fossify.messages.extensions.deleteConversation
|
||||||
import org.fossify.messages.extensions.deleteMessage
|
import org.fossify.messages.extensions.deleteMessage
|
||||||
import org.fossify.messages.extensions.deleteScheduledMessage
|
import org.fossify.messages.extensions.deleteScheduledMessage
|
||||||
import org.fossify.messages.extensions.deleteSmsDraft
|
|
||||||
import org.fossify.messages.extensions.dialNumber
|
import org.fossify.messages.extensions.dialNumber
|
||||||
import org.fossify.messages.extensions.emptyMessagesRecycleBinForConversation
|
import org.fossify.messages.extensions.emptyMessagesRecycleBinForConversation
|
||||||
import org.fossify.messages.extensions.getAddresses
|
import org.fossify.messages.extensions.getAddresses
|
||||||
|
|
@ -282,7 +281,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
)
|
)
|
||||||
|
|
||||||
val smsDraft = getSmsDraft(threadId)
|
val smsDraft = getSmsDraft(threadId)
|
||||||
if (smsDraft != null) {
|
if (!smsDraft.isNullOrEmpty()) {
|
||||||
binding.messageHolder.threadTypeMessage.setText(smsDraft)
|
binding.messageHolder.threadTypeMessage.setText(smsDraft)
|
||||||
}
|
}
|
||||||
isActivityVisible = true
|
isActivityVisible = true
|
||||||
|
|
@ -307,17 +306,16 @@ class ThreadActivity : SimpleActivity() {
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
val draftMessage = binding.messageHolder.threadTypeMessage.value
|
saveDraftMessage()
|
||||||
if (draftMessage.isNotEmpty() && getAttachmentSelections().isEmpty()) {
|
|
||||||
saveSmsDraft(draftMessage, threadId)
|
|
||||||
} else {
|
|
||||||
deleteSmsDraft(threadId)
|
|
||||||
}
|
|
||||||
|
|
||||||
bus?.post(Events.RefreshMessages())
|
bus?.post(Events.RefreshMessages())
|
||||||
isActivityVisible = false
|
isActivityVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
saveDraftMessage()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
isAttachmentPickerVisible = false
|
isAttachmentPickerVisible = false
|
||||||
if (binding.messageHolder.attachmentPickerHolder.isVisible()) {
|
if (binding.messageHolder.attachmentPickerHolder.isVisible()) {
|
||||||
|
|
@ -332,6 +330,15 @@ class ThreadActivity : SimpleActivity() {
|
||||||
bus?.unregister(this)
|
bus?.unregister(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun saveDraftMessage() {
|
||||||
|
val draftMessage = binding.messageHolder.threadTypeMessage.value
|
||||||
|
if (getAttachmentSelections().isEmpty()) {
|
||||||
|
saveSmsDraft(draftMessage, threadId)
|
||||||
|
} else {
|
||||||
|
saveSmsDraft("", threadId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun refreshMenuItems() {
|
private fun refreshMenuItems() {
|
||||||
val firstPhoneNumber = participants.firstOrNull()?.phoneNumbers?.firstOrNull()?.value
|
val firstPhoneNumber = participants.firstOrNull()?.phoneNumbers?.firstOrNull()?.value
|
||||||
val archiveAvailable = config.isArchiveAvailable
|
val archiveAvailable = config.isArchiveAvailable
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.fossify.messages.adapters
|
package org.fossify.messages.adapters
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
|
@ -10,7 +11,11 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||||
import org.fossify.commons.adapters.MyRecyclerViewListAdapter
|
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.SimpleContactsHelper
|
||||||
import org.fossify.commons.helpers.ensureBackgroundThread
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.commons.views.MyRecyclerView
|
import org.fossify.commons.views.MyRecyclerView
|
||||||
|
|
@ -22,11 +27,20 @@ import org.fossify.messages.models.Conversation
|
||||||
|
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
abstract class BaseConversationsAdapter(
|
abstract class BaseConversationsAdapter(
|
||||||
activity: SimpleActivity, recyclerView: MyRecyclerView, onRefresh: () -> Unit, itemClick: (Any) -> Unit
|
activity: SimpleActivity,
|
||||||
) : MyRecyclerViewListAdapter<Conversation>(activity, recyclerView, ConversationDiffCallback(), itemClick, onRefresh),
|
recyclerView: MyRecyclerView,
|
||||||
|
onRefresh: () -> Unit,
|
||||||
|
itemClick: (Any) -> Unit
|
||||||
|
) : MyRecyclerViewListAdapter<Conversation>(
|
||||||
|
activity,
|
||||||
|
recyclerView,
|
||||||
|
ConversationDiffCallback(),
|
||||||
|
itemClick,
|
||||||
|
onRefresh
|
||||||
|
),
|
||||||
RecyclerViewFastScroller.OnPopupTextUpdate {
|
RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||||
private var fontSize = activity.getTextSize()
|
private var fontSize = activity.getTextSize()
|
||||||
private var drafts = HashMap<Long, String?>()
|
private var drafts = HashMap<Long, String>()
|
||||||
|
|
||||||
private var recyclerViewState: Parcelable? = null
|
private var recyclerViewState: Parcelable? = null
|
||||||
|
|
||||||
|
|
@ -39,24 +53,32 @@ abstract class BaseConversationsAdapter(
|
||||||
|
|
||||||
registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onChanged() = restoreRecyclerViewState()
|
override fun onChanged() = restoreRecyclerViewState()
|
||||||
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) = restoreRecyclerViewState()
|
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) =
|
||||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) = restoreRecyclerViewState()
|
restoreRecyclerViewState()
|
||||||
|
|
||||||
|
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) =
|
||||||
|
restoreRecyclerViewState()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
fun updateFontSize() {
|
fun updateFontSize() {
|
||||||
fontSize = activity.getTextSize()
|
fontSize = activity.getTextSize()
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateConversations(newConversations: ArrayList<Conversation>, commitCallback: (() -> Unit)? = null) {
|
fun updateConversations(
|
||||||
|
newConversations: ArrayList<Conversation>,
|
||||||
|
commitCallback: (() -> Unit)? = null
|
||||||
|
) {
|
||||||
saveRecyclerViewState()
|
saveRecyclerViewState()
|
||||||
submitList(newConversations.toList(), commitCallback)
|
submitList(newConversations.toList(), commitCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
fun updateDrafts() {
|
fun updateDrafts() {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
val newDrafts = HashMap<Long, String?>()
|
val newDrafts = HashMap<Long, String>()
|
||||||
fetchDrafts(newDrafts)
|
fetchDrafts(newDrafts)
|
||||||
if (drafts.hashCode() != newDrafts.hashCode()) {
|
if (drafts.hashCode() != newDrafts.hashCode()) {
|
||||||
drafts = newDrafts
|
drafts = newDrafts
|
||||||
|
|
@ -69,7 +91,8 @@ abstract class BaseConversationsAdapter(
|
||||||
|
|
||||||
override fun getSelectableItemCount() = itemCount
|
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
|
override fun getIsItemSelectable(position: Int) = true
|
||||||
|
|
||||||
|
|
@ -88,7 +111,11 @@ abstract class BaseConversationsAdapter(
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val conversation = getItem(position)
|
val conversation = getItem(position)
|
||||||
holder.bindView(conversation, allowSingleClick = true, allowLongClick = true) { itemView, _ ->
|
holder.bindView(
|
||||||
|
conversation,
|
||||||
|
allowSingleClick = true,
|
||||||
|
allowLongClick = true
|
||||||
|
) { itemView, _ ->
|
||||||
setupView(itemView, conversation)
|
setupView(itemView, conversation)
|
||||||
}
|
}
|
||||||
bindViewHolder(holder)
|
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()
|
drafts.clear()
|
||||||
for ((threadId, draft) in activity.getAllDrafts()) {
|
for ((threadId, draft) in activity.getAllDrafts()) {
|
||||||
drafts[threadId] = draft
|
drafts[threadId] = draft
|
||||||
|
|
@ -115,7 +142,7 @@ abstract class BaseConversationsAdapter(
|
||||||
ItemConversationBinding.bind(view).apply {
|
ItemConversationBinding.bind(view).apply {
|
||||||
root.setupViewBackground(activity)
|
root.setupViewBackground(activity)
|
||||||
val smsDraft = drafts[conversation.threadId]
|
val smsDraft = drafts[conversation.threadId]
|
||||||
draftIndicator.beVisibleIf(smsDraft != null)
|
draftIndicator.beVisibleIf(!smsDraft.isNullOrEmpty())
|
||||||
draftIndicator.setTextColor(properPrimaryColor)
|
draftIndicator.setTextColor(properPrimaryColor)
|
||||||
|
|
||||||
pinIndicator.beVisibleIf(activity.config.pinnedConversations.contains(conversation.threadId.toString()))
|
pinIndicator.beVisibleIf(activity.config.pinnedConversations.contains(conversation.threadId.toString()))
|
||||||
|
|
@ -160,7 +187,12 @@ abstract class BaseConversationsAdapter(
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleContactsHelper(activity).loadContactImage(conversation.photoUri, conversationImage, conversation.title, placeholder)
|
SimpleContactsHelper(activity).loadContactImage(
|
||||||
|
conversation.photoUri,
|
||||||
|
conversationImage,
|
||||||
|
conversation.title,
|
||||||
|
placeholder
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1064,8 +1064,8 @@ fun Context.getSmsDraft(threadId: Long): String? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getAllDrafts(): HashMap<Long, String?> {
|
fun Context.getAllDrafts(): HashMap<Long, String> {
|
||||||
val drafts = HashMap<Long, String?>()
|
val drafts = HashMap<Long, String>()
|
||||||
val uri = Sms.Draft.CONTENT_URI
|
val uri = Sms.Draft.CONTENT_URI
|
||||||
val projection = arrayOf(Sms.BODY, Sms.THREAD_ID)
|
val projection = arrayOf(Sms.BODY, Sms.THREAD_ID)
|
||||||
|
|
||||||
|
|
@ -1075,20 +1075,19 @@ fun Context.getAllDrafts(): HashMap<Long, String?> {
|
||||||
while (it.moveToNext()) {
|
while (it.moveToNext()) {
|
||||||
val threadId = it.getLongValue(Sms.THREAD_ID)
|
val threadId = it.getLongValue(Sms.THREAD_ID)
|
||||||
val draft = it.getStringValue(Sms.BODY)
|
val draft = it.getStringValue(Sms.BODY)
|
||||||
if (draft != null) {
|
if (!draft.isNullOrEmpty()) {
|
||||||
drafts[threadId] = draft
|
drafts[threadId] = draft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
return drafts
|
return drafts
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.saveSmsDraft(body: String, threadId: Long) {
|
fun Context.saveSmsDraft(body: String, threadId: Long) {
|
||||||
deleteSmsDraft(threadId)
|
|
||||||
|
|
||||||
val uri = Sms.Draft.CONTENT_URI
|
val uri = Sms.Draft.CONTENT_URI
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = ContentValues().apply {
|
||||||
put(Sms.BODY, body)
|
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) {
|
fun Context.updateLastConversationMessage(threadId: Long) {
|
||||||
updateLastConversationMessage(setOf(threadId))
|
updateLastConversationMessage(setOf(threadId))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue