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,
) : ListAdapter<VisualDownloadCached, DownloadAdapter.DownloadViewHolder>(DiffCallback()) {
private var showDeleteCheckbox: Boolean = false
private var isMultiDeleteState: Boolean = false
private val selectedIds: HashMap<Int, Boolean> = HashMap()
companion object {
@ -127,20 +127,16 @@ class DownloadAdapter(
handleChildDownload(card, formattedSize)
} else handleParentDownload(card, formattedSize)
// 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)
if (isMultiDeleteState) {
deleteCheckbox.setOnCheckedChangeListener { _, isChecked ->
selectedIds[data.id] = isChecked
selectedChangedCallback.invoke(data.id, data.name, isChecked)
}
} else deleteCheckbox.setOnCheckedChangeListener(null)
deleteCheckbox.apply {
isVisible = showDeleteCheckbox
isVisible = isMultiDeleteState
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.isVisible = !showDeleteCheckbox
downloadButton.isVisible = !isMultiDeleteState
episodeHolder.apply {
setOnClickListener {
@ -184,16 +180,6 @@ class DownloadAdapter(
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")
@ -202,7 +188,7 @@ class DownloadAdapter(
formattedSize: String
) {
downloadButton.isVisible = false
downloadHeaderGotoChild.isVisible = !showDeleteCheckbox
downloadHeaderGotoChild.isVisible = !isMultiDeleteState
try {
downloadHeaderInfo.text = downloadHeaderInfo.context.getString(R.string.extra_info_format).format(
@ -218,16 +204,6 @@ class DownloadAdapter(
episodeHolder.setOnClickListener {
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?) {
@ -277,12 +253,6 @@ class DownloadAdapter(
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) {
if (showDeleteCheckbox == visible) return
showDeleteCheckbox = visible
notifyItemRangeChanged(0, itemCount)
@SuppressLint("NotifyDataSetChanged")
fun setIsMultiDeleteState(value: Boolean) {
if (isMultiDeleteState == value) return
isMultiDeleteState = value
if (!value) {
selectedIds.clear()
notifyDataSetChanged()
} else notifyItemRangeChanged(0, itemCount)
}
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>() {
override fun areItemsTheSame(oldItem: VisualDownloadCached, newItem: VisualDownloadCached): Boolean {
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 -> {
activity?.let { act ->
val info =

View file

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

View file

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