feat: option to only delete watched videos

This commit is contained in:
Bnyro 2024-11-17 21:00:59 +01:00
parent 9012a582ea
commit 9ab76ba47b
4 changed files with 26 additions and 19 deletions

View File

@ -87,16 +87,17 @@ object DatabaseHelper {
} }
} }
suspend fun isVideoWatched(videoId: String, duration: Long): Boolean = withContext(Dispatchers.IO) {
val historyItem = Database.watchPositionDao()
.findById(videoId) ?: return@withContext false
val progress = historyItem.position / 1000
// show video only in feed when watched less than 90%
return@withContext progress > 0.9f * duration
}
suspend fun filterUnwatched(streams: List<StreamItem>): List<StreamItem> { suspend fun filterUnwatched(streams: List<StreamItem>): List<StreamItem> {
return streams.filter { return streams.filter {
withContext(Dispatchers.IO) { !isVideoWatched(it.url.orEmpty().toID(), it.duration ?: 0)
val historyItem = Database.watchPositionDao()
.findById(it.url.orEmpty().toID()) ?: return@withContext true
val progress = historyItem.position / 1000
val duration = it.duration ?: 0
// show video only in feed when watched less than 90%
progress < 0.9f * duration
}
} }
} }
@ -105,14 +106,7 @@ object DatabaseHelper {
unfinished: Boolean = true unfinished: Boolean = true
): List<WatchHistoryItem> { ): List<WatchHistoryItem> {
return streams.filter { return streams.filter {
withContext(Dispatchers.IO) { unfinished xor isVideoWatched(it.videoId, it.duration ?: 0)
val historyItem = Database.watchPositionDao()
.findById(it.videoId) ?: return@withContext true
val progress = historyItem.position / 1000
val duration = it.duration ?: 0
// show video only in feed when watched less than 90%
if (unfinished) progress < 0.9f * duration else progress > 0.9f * duration
}
} }
} }

View File

@ -148,6 +148,8 @@ class DownloadsAdapter(
.show() .show()
} }
fun itemAt(index: Int) = downloads[index]
fun deleteDownload(position: Int) { fun deleteDownload(position: Int) {
val download = downloads[position].download val download = downloads[position].download
val items = downloads[position].downloadItems val items = downloads[position].downloadItems

View File

@ -24,6 +24,7 @@ import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.FragmentDownloadContentBinding import com.github.libretube.databinding.FragmentDownloadContentBinding
import com.github.libretube.databinding.FragmentDownloadsBinding import com.github.libretube.databinding.FragmentDownloadsBinding
import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.DatabaseHolder.Database import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.db.obj.DownloadWithItems import com.github.libretube.db.obj.DownloadWithItems
import com.github.libretube.db.obj.filterByTab import com.github.libretube.db.obj.filterByTab
@ -270,14 +271,23 @@ class DownloadsFragmentPage : DynamicLayoutManagerFragment() {
} }
private fun showDeleteAllDialog(context: Context, adapter: DownloadsAdapter) { private fun showDeleteAllDialog(context: Context, adapter: DownloadsAdapter) {
var onlyDeleteWatchedVideos = false
MaterialAlertDialogBuilder(context) MaterialAlertDialogBuilder(context)
.setTitle(R.string.delete_all) .setTitle(R.string.delete_all)
.setMessage(R.string.irreversible) .setMultiChoiceItems(arrayOf(getString(R.string.delete_only_watched_videos)), null) { _, _, selected ->
onlyDeleteWatchedVideos = selected
}
.setPositiveButton(R.string.okay) { _, _ -> .setPositiveButton(R.string.okay) { _, _ ->
lifecycleScope.launch {
for (downloadIndex in downloads.size - 1 downTo 0) { for (downloadIndex in downloads.size - 1 downTo 0) {
val download = adapter.itemAt(downloadIndex).download
if (!onlyDeleteWatchedVideos || DatabaseHelper.isVideoWatched(download.videoId, download.duration ?: 0)) {
adapter.deleteDownload(downloadIndex) adapter.deleteDownload(downloadIndex)
} }
} }
}
}
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.show() .show()
} }

View File

@ -521,6 +521,7 @@
<string name="dialog_play_offline_title">A local version of this video is available.</string> <string name="dialog_play_offline_title">A local version of this video is available.</string>
<string name="dialog_play_offline_body">Would you like to play the video from the download folder?</string> <string name="dialog_play_offline_body">Would you like to play the video from the download folder?</string>
<string name="view_count">%1$s views</string> <string name="view_count">%1$s views</string>
<string name="delete_only_watched_videos">Only delete already watched videos</string>
<!-- Notification channel strings --> <!-- Notification channel strings -->
<string name="download_channel_name">Download Service</string> <string name="download_channel_name">Download Service</string>