Merge pull request #7181 from Bnyro/master

fix: various bugs when deleting single or all downloads
This commit is contained in:
Bnyro 2025-03-08 12:35:47 +01:00 committed by GitHub
commit ccc69dca2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 25 deletions

View File

@ -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<DownloadWithItems, DownloadsViewHolder>(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)

View File

@ -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<DownloadWithItems>()
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 =