From 61334db826bfe08d6fe2319ad0b7764a0151eb08 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Fri, 10 Feb 2023 18:10:17 +0100 Subject: [PATCH] Option to mark videos as watched --- .../libretube/ui/adapters/PlaylistAdapter.kt | 2 +- .../libretube/ui/adapters/VideosAdapter.kt | 12 +++- .../ui/fragments/SubscriptionsFragment.kt | 8 +-- .../ui/sheets/VideoOptionsBottomSheet.kt | 66 ++++++++++++++----- app/src/main/res/values/strings.xml | 1 + 5 files changed, 68 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/adapters/PlaylistAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/PlaylistAdapter.kt index 93d331783..52165a551 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/PlaylistAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/PlaylistAdapter.kt @@ -36,7 +36,7 @@ class PlaylistAdapter( override fun getItemCount(): Int { return when (playlistType) { PlaylistType.PUBLIC -> videoFeed.size - else -> visibleCount + else -> minOf(visibleCount, videoFeed.size) } } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/VideosAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/VideosAdapter.kt index cf2139337..0890a520d 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/VideosAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/VideosAdapter.kt @@ -42,7 +42,7 @@ class VideosAdapter( override fun getItemCount(): Int { return when { showAllAtOnce -> streamItems.size - else -> visibleCount + else -> minOf(streamItems.size, visibleCount) } } @@ -63,6 +63,16 @@ class VideosAdapter( notifyItemRangeInserted(feedSize, newItems.size) } + fun removeItemById(videoId: String) { + val index = streamItems.indexOfFirst { + it.url?.toID() == videoId + }.takeIf { it > 0 } ?: return + streamItems.removeAt(index) + visibleCount -= 1 + notifyItemRemoved(index) + notifyItemRangeChanged(index, itemCount) + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideosViewHolder { val layoutInflater = LayoutInflater.from(parent.context) return when { diff --git a/app/src/main/java/com/github/libretube/ui/fragments/SubscriptionsFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/SubscriptionsFragment.kt index 526ec633e..046f13da2 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/SubscriptionsFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/SubscriptionsFragment.kt @@ -25,7 +25,7 @@ class SubscriptionsFragment : BaseFragment() { private lateinit var binding: FragmentSubscriptionsBinding private val viewModel: SubscriptionsViewModel by activityViewModels() - private var subscriptionAdapter: VideosAdapter? = null + var subscriptionsAdapter: VideosAdapter? = null private var selectedSortOrder = PreferenceHelper.getInt(PreferenceKeys.FEED_SORT_ORDER, 0) set(value) { PreferenceHelper.putInt(PreferenceKeys.FEED_SORT_ORDER, value) @@ -141,7 +141,7 @@ class SubscriptionsFragment : BaseFragment() { // scroll view is at bottom if (viewModel.videoFeed.value == null) return@addOnScrollChangedListener binding.subRefresh.isRefreshing = true - subscriptionAdapter?.updateItems() + subscriptionsAdapter?.updateItems() binding.subRefresh.isRefreshing = false } } @@ -189,12 +189,12 @@ class SubscriptionsFragment : BaseFragment() { if (viewModel.videoFeed.value!!.isEmpty()) View.VISIBLE else View.GONE binding.subProgress.visibility = View.GONE - subscriptionAdapter = VideosAdapter( + subscriptionsAdapter = VideosAdapter( sortedFeed.toMutableList(), showAllAtOnce = false, hideWatched = PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false) ) - binding.subFeed.adapter = subscriptionAdapter + binding.subFeed.adapter = subscriptionsAdapter PreferenceHelper.updateLastFeedWatchedTime() } diff --git a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt index a6243de9c..dde893e74 100644 --- a/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt +++ b/app/src/main/java/com/github/libretube/ui/sheets/VideoOptionsBottomSheet.kt @@ -1,15 +1,25 @@ package com.github.libretube.ui.sheets import android.os.Bundle +import android.util.Log +import androidx.navigation.fragment.NavHostFragment import com.github.libretube.R import com.github.libretube.api.RetrofitInstance +import com.github.libretube.constants.PreferenceKeys +import com.github.libretube.db.DatabaseHolder +import com.github.libretube.db.obj.WatchPosition import com.github.libretube.enums.ShareObjectType +import com.github.libretube.extensions.awaitQuery import com.github.libretube.extensions.toStreamItem import com.github.libretube.helpers.BackgroundHelper +import com.github.libretube.helpers.PlayerHelper +import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.obj.ShareData +import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.dialogs.AddToPlaylistDialog import com.github.libretube.ui.dialogs.DownloadDialog import com.github.libretube.ui.dialogs.ShareDialog +import com.github.libretube.ui.fragments.SubscriptionsFragment import com.github.libretube.util.PlayingQueue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -28,43 +38,46 @@ class VideoOptionsBottomSheet( override fun onCreate(savedInstanceState: Bundle?) { // List that stores the different menu options. In the future could be add more options here. val optionsList = mutableListOf( - context?.getString(R.string.playOnBackground)!!, - context?.getString(R.string.addToPlaylist)!!, - context?.getString(R.string.download)!!, - context?.getString(R.string.share)!! + getString(R.string.playOnBackground), + getString(R.string.addToPlaylist), + getString(R.string.download), + getString(R.string.share) ) - /** - * Check whether the player is running and add queue options - */ + // Check whether the player is running and add queue options if (PlayingQueue.isNotEmpty()) { - optionsList += context?.getString(R.string.play_next)!! - optionsList += context?.getString(R.string.add_to_queue)!! + optionsList += getString(R.string.play_next) + optionsList += getString(R.string.add_to_queue) + } + + // show the mark as watched option if watch positions are enabled + if (PlayerHelper.watchPositionsEnabled) { + optionsList += getString(R.string.mark_as_watched) } setSimpleItems(optionsList) { which -> when (optionsList[which]) { // Start the background mode - context?.getString(R.string.playOnBackground) -> { + getString(R.string.playOnBackground) -> { BackgroundHelper.playOnBackground(requireContext(), videoId) } // Add Video to Playlist Dialog - context?.getString(R.string.addToPlaylist) -> { + getString(R.string.addToPlaylist) -> { AddToPlaylistDialog(videoId).show( parentFragmentManager, AddToPlaylistDialog::class.java.name ) } - context?.getString(R.string.download) -> { + getString(R.string.download) -> { val downloadDialog = DownloadDialog(videoId) downloadDialog.show(parentFragmentManager, DownloadDialog::class.java.name) } - context?.getString(R.string.share) -> { + getString(R.string.share) -> { val shareDialog = ShareDialog(videoId, ShareObjectType.VIDEO, shareData) // using parentFragmentManager is important here shareDialog.show(parentFragmentManager, ShareDialog::class.java.name) } - context?.getString(R.string.play_next) -> { + getString(R.string.play_next) -> { CoroutineScope(Dispatchers.IO).launch { try { PlayingQueue.addAsNext( @@ -76,7 +89,7 @@ class VideoOptionsBottomSheet( } } } - context?.getString(R.string.add_to_queue) -> { + getString(R.string.add_to_queue) -> { CoroutineScope(Dispatchers.IO).launch { try { PlayingQueue.add( @@ -88,6 +101,29 @@ class VideoOptionsBottomSheet( } } } + getString(R.string.mark_as_watched) -> { + val watchPosition = WatchPosition(videoId, Long.MAX_VALUE) + awaitQuery { + DatabaseHolder.Database.watchPositionDao().insertAll(watchPosition) + } + if (PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)) { + // get the host fragment containing the current fragment + val navHostFragment = + (context as MainActivity).supportFragmentManager.findFragmentById( + R.id.fragment + ) as NavHostFragment? + // get the current fragment + val fragment = navHostFragment?.childFragmentManager?.fragments?.firstOrNull() + Log.e( + "fragments", + navHostFragment?.childFragmentManager?.fragments.orEmpty() + .joinToString(", ") { it::class.java.name.toString() } + ) + (fragment as? SubscriptionsFragment)?.subscriptionsAdapter?.removeItemById( + videoId + ) + } + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 614718da7..1d27da100 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -441,6 +441,7 @@ Help FAQ Codecs + Mark as watched Download Service