Much better fix

This commit is contained in:
Luna712 2024-07-07 12:11:53 -06:00 committed by GitHub
parent fc2e2ec0f9
commit de2240d9e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 23 additions and 75 deletions

View file

@ -90,7 +90,7 @@ class DownloadAdapter(
private val selectedChangedCallback: (Int, String, Boolean) -> Unit, private val selectedChangedCallback: (Int, String, Boolean) -> Unit,
) : ListAdapter<VisualDownloadCached, DownloadAdapter.DownloadViewHolder>(DiffCallback()) { ) : ListAdapter<VisualDownloadCached, DownloadAdapter.DownloadViewHolder>(DiffCallback()) {
private var showDeleteCheckbox: Boolean = false private var isMultiDeleteState: Boolean = false
private val selectedIds: HashMap<Int, Boolean> = HashMap() private val selectedIds: HashMap<Int, Boolean> = HashMap()
companion object { companion object {
@ -127,20 +127,16 @@ class DownloadAdapter(
handleChildDownload(card, formattedSize) handleChildDownload(card, formattedSize)
} else handleParentDownload(card, formattedSize) } else handleParentDownload(card, formattedSize)
// This is crappy but we disable view recycling for the if (isMultiDeleteState) {
// ViewHolder when showDeleteCheckbox is true. This means deleteCheckbox.setOnCheckedChangeListener { _, isChecked ->
// that RecyclerView won't reuse these views when scrolling, selectedIds[data.id] = isChecked
// thereby ensuring that the checkbox states are preserved. selectedChangedCallback.invoke(data.id, data.name, isChecked)
setIsRecyclable(!showDeleteCheckbox) }
} else deleteCheckbox.setOnCheckedChangeListener(null)
deleteCheckbox.apply { deleteCheckbox.apply {
isVisible = showDeleteCheckbox isVisible = isMultiDeleteState
isChecked = selectedIds[card.data.id] == true isChecked = selectedIds[card.data.id] == true
setOnCheckedChangeListener(null)
setOnCheckedChangeListener { _, isChecked ->
selectedIds[card.data.id] = isChecked
selectedChangedCallback.invoke(card.data.id, card.data.name, isChecked)
}
} }
} }
} }
@ -173,7 +169,7 @@ class DownloadAdapter(
} }
downloadButton.setDefaultClickListener(card.child, downloadHeaderInfo, mediaClickCallback) downloadButton.setDefaultClickListener(card.child, downloadHeaderInfo, mediaClickCallback)
downloadButton.isVisible = !showDeleteCheckbox downloadButton.isVisible = !isMultiDeleteState
episodeHolder.apply { episodeHolder.apply {
setOnClickListener { setOnClickListener {
@ -184,16 +180,6 @@ class DownloadAdapter(
true true
} }
} }
deleteCheckbox.apply {
isVisible = showDeleteCheckbox
isChecked = selectedIds[card.data.id] == true
setOnCheckedChangeListener(null)
setOnCheckedChangeListener { _, isChecked ->
selectedIds[card.data.id] = isChecked
selectedChangedCallback.invoke(card.data.id, card.data.name, isChecked)
}
}
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -202,7 +188,7 @@ class DownloadAdapter(
formattedSize: String formattedSize: String
) { ) {
downloadButton.isVisible = false downloadButton.isVisible = false
downloadHeaderGotoChild.isVisible = !showDeleteCheckbox downloadHeaderGotoChild.isVisible = !isMultiDeleteState
try { try {
downloadHeaderInfo.text = downloadHeaderInfo.context.getString(R.string.extra_info_format).format( downloadHeaderInfo.text = downloadHeaderInfo.context.getString(R.string.extra_info_format).format(
@ -218,16 +204,6 @@ class DownloadAdapter(
episodeHolder.setOnClickListener { episodeHolder.setOnClickListener {
headerClickCallback.invoke(DownloadHeaderClickEvent(DOWNLOAD_ACTION_GO_TO_CHILD, card.data)) headerClickCallback.invoke(DownloadHeaderClickEvent(DOWNLOAD_ACTION_GO_TO_CHILD, card.data))
} }
deleteCheckbox.apply {
isVisible = showDeleteCheckbox
isChecked = selectedIds[card.data.id] == true
setOnCheckedChangeListener(null)
setOnCheckedChangeListener { _, isChecked ->
selectedIds[card.data.id] = isChecked
selectedChangedCallback.invoke(card.data.id, card.data.name, isChecked)
}
}
} }
private fun bindChild(card: VisualDownloadChildCached?) { private fun bindChild(card: VisualDownloadChildCached?) {
@ -277,12 +253,6 @@ class DownloadAdapter(
mediaClickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, data)) mediaClickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, data))
} }
} }
// This is crappy but we disable view recycling for the
// ViewHolder when showDeleteCheckbox is true. This means
// that RecyclerView won't reuse these views when scrolling,
// thereby ensuring that the checkbox states are preserved.
setIsRecyclable(!showDeleteCheckbox)
} }
} }
@ -308,10 +278,14 @@ class DownloadAdapter(
} }
} }
fun setDeleteCheckboxVisibility(visible: Boolean) { @SuppressLint("NotifyDataSetChanged")
if (showDeleteCheckbox == visible) return fun setIsMultiDeleteState(value: Boolean) {
showDeleteCheckbox = visible if (isMultiDeleteState == value) return
notifyItemRangeChanged(0, itemCount) isMultiDeleteState = value
if (!value) {
selectedIds.clear()
notifyDataSetChanged()
} else notifyItemRangeChanged(0, itemCount)
} }
fun updateSelectedItem(id: Int, isSelected: Boolean) { fun updateSelectedItem(id: Int, isSelected: Boolean) {
@ -333,15 +307,6 @@ class DownloadAdapter(
} }
} }
@SuppressLint("NotifyDataSetChanged")
fun clearSelectedIds() {
if (selectedIds.isNotEmpty()) {
selectedIds.clear()
showDeleteCheckbox = false
notifyDataSetChanged()
}
}
class DiffCallback : DiffUtil.ItemCallback<VisualDownloadCached>() { class DiffCallback : DiffUtil.ItemCallback<VisualDownloadCached>() {
override fun areItemsTheSame(oldItem: VisualDownloadCached, newItem: VisualDownloadCached): Boolean { override fun areItemsTheSame(oldItem: VisualDownloadCached, newItem: VisualDownloadCached): Boolean {
return oldItem.data.id == newItem.data.id return oldItem.data.id == newItem.data.id

View file

@ -80,21 +80,6 @@ object DownloadButtonSetup {
} }
} }
} }
DOWNLOAD_ACTION_LONG_CLICK -> {
activity?.let { act ->
val length =
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
act,
click.data.id
)?.fileLength
?: 0
if (length > 0) {
showToast(R.string.delete, Toast.LENGTH_LONG)
} else {
showToast(R.string.download, Toast.LENGTH_LONG)
}
}
}
DOWNLOAD_ACTION_PLAY_FILE -> { DOWNLOAD_ACTION_PLAY_FILE -> {
activity?.let { act -> activity?.let { act ->
val info = val info =

View file

@ -200,11 +200,11 @@ class DownloadFragment : Fragment() {
context?.let { ctx -> downloadsViewModel.handleMultiDelete(ctx) } context?.let { ctx -> downloadsViewModel.handleMultiDelete(ctx) }
} }
binding?.downloadDeleteToolbar?.btnCancel?.setOnClickListener { binding?.downloadDeleteToolbar?.btnCancel?.setOnClickListener {
adapter?.clearSelectedIds() adapter?.setIsMultiDeleteState(false)
downloadsViewModel.clearSelectedIds() downloadsViewModel.clearSelectedIds()
} }
adapter?.setDeleteCheckboxVisibility(true) adapter?.setIsMultiDeleteState(true)
} else { } else {
binding?.downloadDeleteToolbar?.downloadDeleteToolbar?.isVisible = false binding?.downloadDeleteToolbar?.downloadDeleteToolbar?.isVisible = false
binding?.downloadStorageAppbar?.isVisible = binding?.downloadStorageAppbar?.isVisible =
@ -212,9 +212,7 @@ class DownloadFragment : Fragment() {
!downloadsViewModel.headerCards.value.isNullOrEmpty() && !downloadsViewModel.headerCards.value.isNullOrEmpty() &&
downloadsViewModel.usedBytes.value?.let { it > 0 } == true downloadsViewModel.usedBytes.value?.let { it > 0 } == true
adapter?.setDeleteCheckboxVisibility(false) adapter?.setIsMultiDeleteState(false)
adapter?.clearSelectedIds()
downloadsViewModel.clearSelectedIds() downloadsViewModel.clearSelectedIds()
} }
} }

View file

@ -62,9 +62,9 @@ class DownloadViewModel : ViewModel() {
} }
fun filterSelectedIds(updatedIds: Set<Int>) { fun filterSelectedIds(updatedIds: Set<Int>) {
val currentSelectedIds = _selectedIds.value ?: return val currentSelectedIds = selectedIds.value ?: return
val filteredIds = currentSelectedIds.filterKeys { updatedIds.contains(it) } val filteredIds = currentSelectedIds.filterKeys { updatedIds.contains(it) }
_selectedIds.value = HashMap(filteredIds) _selectedIds.postValue(HashMap(filteredIds))
} }
fun clearSelectedIds() { fun clearSelectedIds() {