Use DiffUtil at conversations screen
This commit is contained in:
parent
3092253022
commit
9bdc8b6f7e
|
@ -299,7 +299,7 @@ class MainActivity : SimpleActivity() {
|
|||
val currAdapter = conversations_list.adapter
|
||||
if (currAdapter == null) {
|
||||
hideKeyboard()
|
||||
ConversationsAdapter(this, sortedConversations, conversations_list) {
|
||||
ConversationsAdapter(this, conversations_list) {
|
||||
Intent(this, ThreadActivity::class.java).apply {
|
||||
val conversation = it as Conversation
|
||||
putExtra(THREAD_ID, conversation.threadId)
|
||||
|
@ -308,6 +308,7 @@ class MainActivity : SimpleActivity() {
|
|||
}
|
||||
}.apply {
|
||||
conversations_list.adapter = this
|
||||
updateConversations(sortedConversations)
|
||||
}
|
||||
|
||||
if (areSystemAnimationsEnabled) {
|
||||
|
@ -315,12 +316,13 @@ class MainActivity : SimpleActivity() {
|
|||
}
|
||||
} else {
|
||||
try {
|
||||
(currAdapter as ConversationsAdapter).updateConversations(sortedConversations)
|
||||
if (currAdapter.conversations.isEmpty()) {
|
||||
conversations_fastscroller.beGone()
|
||||
no_conversations_placeholder.text = getString(R.string.no_conversations_found)
|
||||
no_conversations_placeholder.beVisible()
|
||||
no_conversations_placeholder_2.beVisible()
|
||||
(currAdapter as ConversationsAdapter).updateConversations(sortedConversations) {
|
||||
if (currAdapter.currentList.isEmpty()) {
|
||||
conversations_fastscroller.beGone()
|
||||
no_conversations_placeholder.text = getString(R.string.no_conversations_found)
|
||||
no_conversations_placeholder.beVisible()
|
||||
no_conversations_placeholder_2.beVisible()
|
||||
}
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
|
|
@ -2,15 +2,18 @@ package com.simplemobiletools.smsmessenger.adapters
|
|||
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Parcelable
|
||||
import android.text.TextUtils
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewListAdapter
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.KEY_PHONE
|
||||
|
@ -26,14 +29,23 @@ import com.simplemobiletools.smsmessenger.models.Conversation
|
|||
import kotlinx.android.synthetic.main.item_conversation.view.*
|
||||
|
||||
class ConversationsAdapter(
|
||||
activity: SimpleActivity, var conversations: ArrayList<Conversation>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
activity: SimpleActivity, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewListAdapter<Conversation>(activity, recyclerView, ConversationDiffCallback(), itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
private var fontSize = activity.getTextSize()
|
||||
private var drafts = HashMap<Long, String?>()
|
||||
|
||||
private var recyclerViewState: Parcelable? = null
|
||||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
fetchDrafts(drafts)
|
||||
setHasStableIds(true)
|
||||
|
||||
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 getActionMenuId() = R.menu.cab_conversations
|
||||
|
@ -71,13 +83,13 @@ class ConversationsAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getSelectableItemCount() = conversations.size
|
||||
override fun getSelectableItemCount() = itemCount
|
||||
|
||||
override fun getIsItemSelectable(position: Int) = true
|
||||
|
||||
override fun getItemSelectionKey(position: Int) = conversations.getOrNull(position)?.hashCode()
|
||||
override fun getItemSelectionKey(position: Int) = currentList.getOrNull(position)?.hashCode()
|
||||
|
||||
override fun getItemKeyPosition(key: Int) = conversations.indexOfFirst { it.hashCode() == key }
|
||||
override fun getItemKeyPosition(key: Int) = currentList.indexOfFirst { it.hashCode() == key }
|
||||
|
||||
override fun onActionModeCreated() {}
|
||||
|
||||
|
@ -86,14 +98,14 @@ class ConversationsAdapter(
|
|||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_conversation, parent)
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val conversation = conversations[position]
|
||||
holder.bindView(conversation, true, true) { itemView, layoutPosition ->
|
||||
val conversation = getItem(position)
|
||||
holder.bindView(conversation, allowSingleClick = true, allowLongClick = true) { itemView, _ ->
|
||||
setupView(itemView, conversation)
|
||||
}
|
||||
bindViewHolder(holder)
|
||||
}
|
||||
|
||||
override fun getItemCount() = conversations.size
|
||||
override fun getItemId(position: Int) = getItem(position).threadId
|
||||
|
||||
override fun onViewRecycled(holder: ViewHolder) {
|
||||
super.onViewRecycled(holder)
|
||||
|
@ -118,8 +130,7 @@ class ConversationsAdapter(
|
|||
}
|
||||
|
||||
val numbersToBlock = getSelectedItems()
|
||||
val positions = getSelectedItemPositions()
|
||||
conversations.removeAll(numbersToBlock)
|
||||
val newList = currentList.toMutableList().apply { removeAll(numbersToBlock) }
|
||||
|
||||
ensureBackgroundThread {
|
||||
numbersToBlock.map { it.phoneNumber }.forEach { number ->
|
||||
|
@ -127,7 +138,7 @@ class ConversationsAdapter(
|
|||
}
|
||||
|
||||
activity.runOnUiThread {
|
||||
removeSelectedItems(positions)
|
||||
submitList(newList)
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
@ -165,25 +176,25 @@ class ConversationsAdapter(
|
|||
return
|
||||
}
|
||||
|
||||
val conversationsToRemove = conversations.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
val positions = getSelectedItemPositions()
|
||||
val conversationsToRemove = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
conversationsToRemove.forEach {
|
||||
activity.deleteConversation(it.threadId)
|
||||
activity.notificationManager.cancel(it.hashCode())
|
||||
}
|
||||
|
||||
try {
|
||||
conversations.removeAll(conversationsToRemove.toSet())
|
||||
val newList = try {
|
||||
currentList.toMutableList().apply { removeAll(conversationsToRemove) }
|
||||
} catch (ignored: Exception) {
|
||||
currentList.toMutableList()
|
||||
}
|
||||
|
||||
activity.runOnUiThread {
|
||||
if (conversationsToRemove.isEmpty()) {
|
||||
if (newList.none { selectedKeys.contains(it.hashCode()) }) {
|
||||
refreshMessages()
|
||||
finishActMode()
|
||||
} else {
|
||||
removeSelectedItems(positions)
|
||||
if (conversations.isEmpty()) {
|
||||
submitList(newList)
|
||||
if (newList.isEmpty()) {
|
||||
refreshMessages()
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +206,7 @@ class ConversationsAdapter(
|
|||
return
|
||||
}
|
||||
|
||||
val conversationsMarkedAsRead = conversations.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
val conversationsMarkedAsRead = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
ensureBackgroundThread {
|
||||
conversationsMarkedAsRead.filter { conversation -> !conversation.read }.forEach {
|
||||
activity.markThreadMessagesRead(it.threadId)
|
||||
|
@ -213,7 +224,7 @@ class ConversationsAdapter(
|
|||
return
|
||||
}
|
||||
|
||||
val conversationsMarkedAsUnread = conversations.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
val conversationsMarkedAsUnread = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
ensureBackgroundThread {
|
||||
conversationsMarkedAsUnread.filter { conversation -> conversation.read }.forEach {
|
||||
activity.markThreadMessagesUnread(it.threadId)
|
||||
|
@ -236,7 +247,7 @@ class ConversationsAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getSelectedItems() = conversations.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
private fun getSelectedItems() = currentList.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<Conversation>
|
||||
|
||||
private fun pinConversation(pin: Boolean) {
|
||||
val conversations = getSelectedItems()
|
||||
|
@ -275,14 +286,9 @@ class ConversationsAdapter(
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun updateConversations(newConversations: ArrayList<Conversation>) {
|
||||
val latestConversations = newConversations.clone() as ArrayList<Conversation>
|
||||
val oldHashCode = conversations.hashCode()
|
||||
val newHashCode = latestConversations.hashCode()
|
||||
if (newHashCode != oldHashCode) {
|
||||
conversations = latestConversations
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
fun updateConversations(newConversations: ArrayList<Conversation>, commitCallback: (() -> Unit)? = null) {
|
||||
saveRecyclerViewState()
|
||||
submitList(newConversations.toList(), commitCallback)
|
||||
}
|
||||
|
||||
fun updateDrafts() {
|
||||
|
@ -346,5 +352,23 @@ class ConversationsAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = conversations.getOrNull(position)?.title ?: ""
|
||||
override fun onChange(position: Int) = currentList.getOrNull(position)?.title ?: ""
|
||||
|
||||
private fun saveRecyclerViewState() {
|
||||
recyclerViewState = recyclerView.layoutManager?.onSaveInstanceState()
|
||||
}
|
||||
|
||||
private fun restoreRecyclerViewState() {
|
||||
recyclerView.layoutManager?.onRestoreInstanceState(recyclerViewState)
|
||||
}
|
||||
|
||||
private class ConversationDiffCallback : DiffUtil.ItemCallback<Conversation>() {
|
||||
override fun areItemsTheSame(oldItem: Conversation, newItem: Conversation): Boolean {
|
||||
return oldItem.areItemsTheSame(newItem)
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: Conversation, newItem: Conversation): Boolean {
|
||||
return oldItem.areContentsTheSame(newItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ data class Conversation(
|
|||
@ColumnInfo(name = "is_scheduled") var isScheduled: Boolean = false
|
||||
) {
|
||||
|
||||
fun areItemsTheSame(other: Conversation): Boolean {
|
||||
return threadId == other.threadId
|
||||
}
|
||||
|
||||
fun areContentsTheSame(other: Conversation): Boolean {
|
||||
return snippet == other.snippet &&
|
||||
date == other.date &&
|
||||
|
|
Loading…
Reference in New Issue