From f1e52a8e6af40adf24caf9cd5d22a402a118f564 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sat, 8 Mar 2025 12:34:46 +0100 Subject: [PATCH] fix: various bugs when deleting single or all downloads --- .../libretube/ui/adapters/DownloadsAdapter.kt | 28 ++++++++++++++++-- .../ui/fragments/DownloadsFragment.kt | 29 +++++-------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt index 501b0cb64..dbade1b62 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/DownloadsAdapter.kt @@ -13,6 +13,7 @@ import androidx.recyclerview.widget.ListAdapter import com.github.libretube.R import com.github.libretube.constants.IntentData import com.github.libretube.databinding.VideoRowBinding +import com.github.libretube.db.DatabaseHelper import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.obj.DownloadWithItems import com.github.libretube.extensions.formatAsFileSize @@ -40,6 +41,8 @@ class DownloadsAdapter( private val downloadTab: DownloadTab, private val toggleDownload: (DownloadWithItems) -> Boolean ) : ListAdapter(DiffUtilItemCallback()) { + val items get() = (0 until itemCount).map { getItem(it) } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadsViewHolder { val binding = VideoRowBinding.inflate( LayoutInflater.from(parent.context), @@ -156,9 +159,9 @@ class DownloadsAdapter( .show() } - fun deleteDownload(position: Int) { - val download = getItem(position).download - val items = getItem(position).downloadItems + private fun deleteDownloadContent(downloadWithItems: DownloadWithItems) { + val download = downloadWithItems.download + val items = downloadWithItems.downloadItems items.forEach { it.path.deleteIfExists() @@ -170,11 +173,30 @@ class DownloadsAdapter( runBlocking(Dispatchers.IO) { DatabaseHolder.Database.downloadDao().deleteDownload(download) } + } + + private fun deleteDownload(position: Int) { + deleteDownloadContent(getItem(position)) + submitList(currentList.toMutableList().also { it.removeAt(position) }) } + fun deleteAllDownloads(onlyDeleteWatched: Boolean) { + val (toDelete, toKeep) = items.partition { + !onlyDeleteWatched || runBlocking(Dispatchers.IO) { + DatabaseHelper.isVideoWatched(it.download.videoId, it.download.duration ?: 0) + } + } + + for (item in toDelete) { + deleteDownloadContent(item) + } + + submitList(toKeep) + } + fun restoreItem(position: Int) { // moves the item back to its initial horizontal position notifyItemRemoved(position) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt index 0e48f2fa9..655993802 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/DownloadsFragment.kt @@ -22,9 +22,7 @@ import com.github.libretube.constants.IntentData import com.github.libretube.constants.PreferenceKeys import com.github.libretube.databinding.FragmentDownloadContentBinding import com.github.libretube.databinding.FragmentDownloadsBinding -import com.github.libretube.db.DatabaseHelper import com.github.libretube.db.DatabaseHolder.Database -import com.github.libretube.db.obj.DownloadWithItems import com.github.libretube.db.obj.filterByTab import com.github.libretube.extensions.ceilHalf import com.github.libretube.extensions.formatAsFileSize @@ -108,7 +106,6 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow private val binding get() = _binding!! private var binder: DownloadService.LocalBinder? = null - private val downloads = mutableListOf() private val downloadReceiver = DownloadReceiver() private lateinit var downloadTab: DownloadTab @@ -172,7 +169,6 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow return@DownloadsAdapter isDownloading.not() } binding.downloadsRecView.adapter = adapter - adapter.submitList(downloads) var selectedSortType = PreferenceHelper.getInt(PreferenceKeys.SELECTED_DOWNLOAD_SORT_TYPE, 0) @@ -197,14 +193,10 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow Database.downloadDao().getAll() } - downloads.clear() - downloads.addAll(dbDownloads.filterByTab(downloadTab)) - - if (downloads.isEmpty()) return@launch - + val downloads = dbDownloads.filterByTab(downloadTab) + adapter.submitList(downloads) sortDownloadList(selectedSortType) - binding.downloadsRecView.setOnDismissListener { position -> adapter.showDeleteDialog(requireContext(), position) // put the item back to the center, as it's currently out of the screen @@ -242,7 +234,7 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow private fun toggleVisibilities() { val binding = _binding ?: return - val isEmpty = downloads.isEmpty() + val isEmpty = adapter.itemCount == 0 binding.downloadsEmpty.isVisible = isEmpty binding.downloadsContainer.isGone = isEmpty binding.deleteAll.isGone = isEmpty @@ -251,10 +243,10 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow private fun sortDownloadList(sortType: Int, previousSortType: Int? = null) { if (previousSortType == null && sortType == 1) { - adapter.submitList(downloads.reversed()) + adapter.submitList(adapter.items.reversed()) } if (previousSortType != null && sortType != previousSortType) { - adapter.submitList(downloads.reversed()) + adapter.submitList(adapter.items.reversed()) } } @@ -267,14 +259,7 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow onlyDeleteWatchedVideos = selected } .setPositiveButton(R.string.okay) { _, _ -> - lifecycleScope.launch { - for (downloadIndex in downloads.size - 1 downTo 0) { - val download = adapter.currentList[downloadIndex].download - if (!onlyDeleteWatchedVideos || DatabaseHelper.isVideoWatched(download.videoId, download.duration ?: 0)) { - adapter.deleteDownload(downloadIndex) - } - } - } + adapter.deleteAllDownloads(onlyDeleteWatchedVideos) } .setNegativeButton(R.string.cancel, null) .show() @@ -312,7 +297,7 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment(R.layout.fragment_dow } fun updateProgress(id: Int, status: DownloadStatus) { - val index = downloads.indexOfFirst { + val index = adapter.items.indexOfFirst { it.downloadItems.any { item -> item.id == id } } val view =