diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt index 4faafb2ea..a53e5cac1 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt @@ -71,8 +71,8 @@ abstract class FeedDAO { :includePartiallyPlayed OR sh.stream_id IS NULL OR sst.stream_id IS NULL - OR (sst.progress_time < ${StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS} - AND sst.progress_time < s.duration * 1000 / 4) + OR (sst.progress_time <= ${StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS} + AND sst.progress_time <= s.duration * 1000 / 4) ) AND ( :uploadDateBefore IS NULL diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 07421a8ea..9358c1654 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -100,9 +100,13 @@ class FeedFragment : BaseStateFragment() { private var oldestSubscriptionUpdate: OffsetDateTime? = null private lateinit var groupAdapter: GroupieAdapter - @State @JvmField var showPlayedItems: ShowItems = ShowItems.DEFAULT + @State @JvmField var feedVisibilityStatus: StreamVisibilityStatus = StreamVisibilityStatus.DEFAULT @State @JvmField var showFutureItems: Boolean = true + private lateinit var showAllMenuItem: MenuItem + private lateinit var hideWatchedMenuItem: MenuItem + private lateinit var hidePartiallyWatchedMenuItem: MenuItem + private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null private var updateListViewModeOnResume = false private var isRefreshing = false @@ -140,7 +144,7 @@ class FeedFragment : BaseStateFragment() { val factory = FeedViewModel.getFactory(requireContext(), groupId) viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java] - showPlayedItems = viewModel.getItemsVisibilityFromPreferences() + feedVisibilityStatus = viewModel.getItemsVisibilityFromPreferences() showFutureItems = viewModel.getShowFutureItemsFromPreferences() viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) } @@ -216,7 +220,15 @@ class FeedFragment : BaseStateFragment() { activity.supportActionBar?.subtitle = groupName inflater.inflate(R.menu.menu_feed_fragment, menu) - updateTogglePlayedItemsButton(menu.findItem(R.id.menu_item_feed_toggle_played_items)) + + val itemVisibilityMenu = menu.findItem(R.id.menu_item_feed_toggle_played_items).subMenu + if (itemVisibilityMenu != null) { + showAllMenuItem = itemVisibilityMenu.findItem(R.id.menu_item_feed_toggle_show_all_items) + hideWatchedMenuItem = itemVisibilityMenu.findItem(R.id.menu_item_feed_toggle_show_played_items) + hidePartiallyWatchedMenuItem = itemVisibilityMenu.findItem(R.id.menu_item_feed_toggle_partially_played_items) + } + + updateItemVisibilityMenu(menu.findItem(R.id.menu_item_feed_toggle_played_items)) updateToggleFutureItemsButton(menu.findItem(R.id.menu_item_feed_toggle_future_items)) } @@ -243,11 +255,11 @@ class FeedFragment : BaseStateFragment() { .show() return true } else if (item.itemId == R.id.menu_item_feed_toggle_show_all_items) { - setShowPlayedItemsMethod(item, ShowItems.DEFAULT) + changeItemsVisibilityStatus(item, StreamVisibilityStatus.DEFAULT) } else if (item.itemId == R.id.menu_item_feed_toggle_show_played_items) { - setShowPlayedItemsMethod(item, ShowItems.WATCHED) + changeItemsVisibilityStatus(item, StreamVisibilityStatus.HIDE_WATCHED) } else if (item.itemId == R.id.menu_item_feed_toggle_partially_played_items) { - setShowPlayedItemsMethod(item, ShowItems.PARTIALLY_WATCHED) + changeItemsVisibilityStatus(item, StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED) } else if (item.itemId == R.id.menu_item_feed_toggle_future_items) { showFutureItems = !item.isChecked updateToggleFutureItemsButton(item) @@ -258,11 +270,11 @@ class FeedFragment : BaseStateFragment() { return super.onOptionsItemSelected(item) } - private fun setShowPlayedItemsMethod(item: MenuItem, showItems: ShowItems) { - showPlayedItems = showItems - viewModel.togglePlayedItems(showPlayedItems) - updateTogglePlayedItemsButton(item) - viewModel.saveShowPlayedItemsToPreferences(showPlayedItems) + private fun changeItemsVisibilityStatus(item: MenuItem, streamVisibilityStatus: StreamVisibilityStatus) { + feedVisibilityStatus = streamVisibilityStatus + viewModel.changeVisibilityState(feedVisibilityStatus) + updateItemVisibilityMenu(item) + viewModel.saveStreamVisibilityStateToPreferences(feedVisibilityStatus) } override fun onDestroyOptionsMenu() { @@ -291,10 +303,28 @@ class FeedFragment : BaseStateFragment() { super.onDestroyView() } - private fun updateTogglePlayedItemsButton(menuItem: MenuItem) { + private fun updateItemVisibilityMenu(menuItem: MenuItem) { + when (feedVisibilityStatus) { + StreamVisibilityStatus.DEFAULT -> { + showAllMenuItem.isVisible = false + hideWatchedMenuItem.isVisible = true + hidePartiallyWatchedMenuItem.isVisible = true + } + StreamVisibilityStatus.HIDE_WATCHED -> { + showAllMenuItem.isVisible = true + hideWatchedMenuItem.isVisible = false + hidePartiallyWatchedMenuItem.isVisible = true + } + else -> { + showAllMenuItem.isVisible = true + hideWatchedMenuItem.isVisible = true + hidePartiallyWatchedMenuItem.isVisible = false + } + } + MenuItemCompat.setTooltipText( menuItem, - getString(R.string.feed_toggle_show_hide_played_items) + getString(R.string.feed_change_stream_visibility_state) ) } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt index 5785c8e3f..46c3443a8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt @@ -28,20 +28,17 @@ import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT import java.time.OffsetDateTime import java.util.concurrent.TimeUnit -enum class ShowItems { - WATCHED, PARTIALLY_WATCHED, DEFAULT -} class FeedViewModel( private val application: Application, groupId: Long = FeedGroupEntity.GROUP_ALL_ID, - initialShowPlayedItems: ShowItems = ShowItems.DEFAULT, + initialStreamVisibility: StreamVisibilityStatus = StreamVisibilityStatus.DEFAULT, initialShowFutureItems: Boolean = true ) : ViewModel() { private val feedDatabaseManager = FeedDatabaseManager(application) - private val toggleShowPlayedItems = BehaviorProcessor.create() - private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems - .startWithItem(initialShowPlayedItems) + private val streamVisibilityState = BehaviorProcessor.create() + private val streamVisibilityStateFlowable = streamVisibilityState + .startWithItem(initialStreamVisibility) .distinctUntilChanged() private val toggleShowFutureItems = BehaviorProcessor.create() @@ -55,12 +52,12 @@ class FeedViewModel( private var combineDisposable = Flowable .combineLatest( FeedEventManager.events(), - toggleShowPlayedItemsFlowable, + streamVisibilityStateFlowable, toggleShowFutureItemsFlowable, feedDatabaseManager.notLoadedCount(groupId), feedDatabaseManager.oldestSubscriptionUpdate(groupId), - Function5 { t1: FeedEventManager.Event, t2: ShowItems, t3: Boolean, + Function5 { t1: FeedEventManager.Event, t2: StreamVisibilityStatus, t3: Boolean, t4: Long, t5: List -> return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull()) } @@ -74,10 +71,10 @@ class FeedViewModel( .getStreams( groupId, !( - showPlayedItems == ShowItems.WATCHED || - showPlayedItems == ShowItems.PARTIALLY_WATCHED + showPlayedItems == StreamVisibilityStatus.HIDE_WATCHED || + showPlayedItems == StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED ), - showPlayedItems != ShowItems.PARTIALLY_WATCHED, + showPlayedItems != StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED, showFutureItems ) .blockingGet(arrayListOf()) @@ -110,7 +107,7 @@ class FeedViewModel( private data class CombineResultEventHolder( val t1: FeedEventManager.Event, - val t2: ShowItems, + val t2: StreamVisibilityStatus, val t3: Boolean, val t4: Long, val t5: OffsetDateTime? @@ -123,20 +120,20 @@ class FeedViewModel( val t4: OffsetDateTime? ) - fun togglePlayedItems(showItems: ShowItems) { - toggleShowPlayedItems.onNext(showItems) + fun changeVisibilityState(streamVisibilityStatus: StreamVisibilityStatus) { + streamVisibilityState.onNext(streamVisibilityStatus) } - fun saveShowPlayedItemsToPreferences(showItems: ShowItems) = + fun saveStreamVisibilityStateToPreferences(streamVisibilityStatus: StreamVisibilityStatus) = PreferenceManager.getDefaultSharedPreferences(application).edit { this.putString( - application.getString(R.string.feed_show_played_items_key), - showItems.toString() + application.getString(R.string.feed_stream_visibility_state_key), + streamVisibilityStatus.toString() ) this.apply() } - fun getItemsVisibilityFromPreferences() = getItemsVisibilityFromPreferences(application) + fun getItemsVisibilityFromPreferences() = getStreamVisibilityStateFromPreferences(application) fun toggleFutureItems(showFutureItems: Boolean) { toggleShowFutureItems.onNext(showFutureItems) @@ -152,13 +149,13 @@ class FeedViewModel( companion object { - private fun getItemsVisibilityFromPreferences(context: Context): ShowItems { + private fun getStreamVisibilityStateFromPreferences(context: Context): StreamVisibilityStatus { val s = PreferenceManager.getDefaultSharedPreferences(context) .getString( - context.getString(R.string.feed_show_played_items_key), - ShowItems.DEFAULT.toString() - ) ?: ShowItems.DEFAULT.toString() - return ShowItems.valueOf(s) + context.getString(R.string.feed_stream_visibility_state_key), + StreamVisibilityStatus.DEFAULT.toString() + ) ?: StreamVisibilityStatus.DEFAULT.toString() + return StreamVisibilityStatus.valueOf(s) } private fun getShowFutureItemsFromPreferences(context: Context) = @@ -170,7 +167,7 @@ class FeedViewModel( App.getApp(), groupId, // Read initial value from preferences - getItemsVisibilityFromPreferences(context.applicationContext), + getStreamVisibilityStateFromPreferences(context.applicationContext), getShowFutureItemsFromPreferences(context.applicationContext) ) } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/StreamVisibilityStatus.kt b/app/src/main/java/org/schabi/newpipe/local/feed/StreamVisibilityStatus.kt new file mode 100644 index 000000000..956594ef3 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/feed/StreamVisibilityStatus.kt @@ -0,0 +1,5 @@ +package org.schabi.newpipe.local.feed + +enum class StreamVisibilityStatus { + DEFAULT, HIDE_WATCHED, HIDE_PARTIALLY_WATCHED +} diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java index b8d2eae2d..be3ab3674 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java @@ -87,7 +87,7 @@ public class HistoryRecordManager { * Marks a stream item as watched such that it is hidden from the feed if watched videos are * hidden. Adds a history entry and updates the stream progress to 100%. * - * @see FeedViewModel#togglePlayedItems + * @see FeedViewModel#changeVisibilityState * @param info the item to mark as watched * @return a Maybe containing the ID of the item if successful */ diff --git a/app/src/main/res/menu/menu_feed_fragment.xml b/app/src/main/res/menu/menu_feed_fragment.xml index fc371b2fe..303d27b6b 100644 --- a/app/src/main/res/menu/menu_feed_fragment.xml +++ b/app/src/main/res/menu/menu_feed_fragment.xml @@ -7,18 +7,18 @@ android:checkable="false" android:checked="false" android:icon="@drawable/ic_visibility_on" - android:title="@string/feed_toggle_show_hide_played_items" + android:title="@string/feed_change_stream_visibility_state" app:showAsAction="ifRoom"> + android:title="@string/feed_stream_visibility_show_all"/> + android:title="@string/feed_stream_visibility_hide_watched"/> + android:title="@string/feed_stream_visibility_hide_partially_watched"/> diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 83f85b934..0bb9b21c2 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -283,7 +283,7 @@ feed_update_threshold_key 300 - feed_show_items + feed_stream_visibility_state feed_show_future_items show_thumbnail_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46a3cad74..854e0db54 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -691,7 +691,7 @@ \nYouTube is an example of a service that offers this fast method with its RSS feed. \n \nSo the choice boils down to what you prefer: speed or precise information. - Show/hide watched items + Show/hide watched streams This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version. Channel\'s avatar thumbnail Created by %s @@ -759,8 +759,8 @@ Unknown quality Show future items Hide future items - Hide Watched and Partially Watched - Hide Watched - Show All + Hide Watched + Hide Fully Watched + Show All Sort \ No newline at end of file