mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +00:00 
			
		
		
		
	First draft of the new feature
This commit is contained in:
		| @@ -32,6 +32,7 @@ abstract class FeedDAO { | ||||
|      * @return the feed streams filtered according to the conditions provided in the parameters | ||||
|      * @see StreamStateEntity.isFinished() | ||||
|      * @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS | ||||
|      * @see StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS | ||||
|      */ | ||||
|     @Query( | ||||
|         """ | ||||
| @@ -66,6 +67,13 @@ abstract class FeedDAO { | ||||
|             OR s.stream_type = 'LIVE_STREAM' | ||||
|             OR s.stream_type = 'AUDIO_LIVE_STREAM' | ||||
|         ) | ||||
|         AND ( | ||||
|             :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) | ||||
|         ) | ||||
|         AND ( | ||||
|             :uploadDateBefore IS NULL | ||||
|             OR s.upload_date IS NULL | ||||
| @@ -79,6 +87,7 @@ abstract class FeedDAO { | ||||
|     abstract fun getStreams( | ||||
|         groupId: Long, | ||||
|         includePlayed: Boolean, | ||||
|         includePartiallyPlayed: Boolean, | ||||
|         uploadDateBefore: OffsetDateTime? | ||||
|     ): Maybe<List<StreamWithState>> | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ public class StreamStateEntity { | ||||
|     /** | ||||
|      * Playback state will not be saved, if playback time is less than this threshold (5000ms = 5s). | ||||
|      */ | ||||
|     private static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000; | ||||
|     public static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000; | ||||
|  | ||||
|     /** | ||||
|      * Stream will be considered finished if the playback time left exceeds this threshold | ||||
|   | ||||
| @@ -43,11 +43,13 @@ class FeedDatabaseManager(context: Context) { | ||||
|     fun getStreams( | ||||
|         groupId: Long, | ||||
|         includePlayedStreams: Boolean, | ||||
|         includePartiallyPlayedStreams: Boolean, | ||||
|         includeFutureStreams: Boolean | ||||
|     ): Maybe<List<StreamWithState>> { | ||||
|         return feedTable.getStreams( | ||||
|             groupId, | ||||
|             includePlayedStreams, | ||||
|             includePartiallyPlayedStreams, | ||||
|             if (includeFutureStreams) null else OffsetDateTime.now() | ||||
|         ) | ||||
|     } | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class FeedFragment : BaseStateFragment<FeedState>() { | ||||
|     private var oldestSubscriptionUpdate: OffsetDateTime? = null | ||||
|  | ||||
|     private lateinit var groupAdapter: GroupieAdapter | ||||
|     @State @JvmField var showPlayedItems: Boolean = true | ||||
|     @State @JvmField var showPlayedItems: ShowItems = ShowItems.DEFAULT | ||||
|     @State @JvmField var showFutureItems: Boolean = true | ||||
|  | ||||
|     private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null | ||||
| @@ -140,7 +140,7 @@ class FeedFragment : BaseStateFragment<FeedState>() { | ||||
|  | ||||
|         val factory = FeedViewModel.getFactory(requireContext(), groupId) | ||||
|         viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java] | ||||
|         showPlayedItems = viewModel.getShowPlayedItemsFromPreferences() | ||||
|         showPlayedItems = viewModel.getItemsVisibilityFromPreferences() | ||||
|         showFutureItems = viewModel.getShowFutureItemsFromPreferences() | ||||
|         viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) } | ||||
|  | ||||
| @@ -242,11 +242,12 @@ class FeedFragment : BaseStateFragment<FeedState>() { | ||||
|                 .create() | ||||
|                 .show() | ||||
|             return true | ||||
|         } else if (item.itemId == R.id.menu_item_feed_toggle_played_items) { | ||||
|             showPlayedItems = !item.isChecked | ||||
|             updateTogglePlayedItemsButton(item) | ||||
|             viewModel.togglePlayedItems(showPlayedItems) | ||||
|             viewModel.saveShowPlayedItemsToPreferences(showPlayedItems) | ||||
|         } else if (item.itemId == R.id.menu_item_feed_toggle_show_all_items) { | ||||
|             setShowPlayedItemsMethod(item, ShowItems.DEFAULT) | ||||
|         } else if (item.itemId == R.id.menu_item_feed_toggle_show_played_items) { | ||||
|             setShowPlayedItemsMethod(item, ShowItems.WATCHED) | ||||
|         } else if (item.itemId == R.id.menu_item_feed_toggle_partially_played_items) { | ||||
|             setShowPlayedItemsMethod(item, ShowItems.PARTIALLY_WATCHED) | ||||
|         } else if (item.itemId == R.id.menu_item_feed_toggle_future_items) { | ||||
|             showFutureItems = !item.isChecked | ||||
|             updateToggleFutureItemsButton(item) | ||||
| @@ -257,6 +258,13 @@ class FeedFragment : BaseStateFragment<FeedState>() { | ||||
|         return super.onOptionsItemSelected(item) | ||||
|     } | ||||
|  | ||||
|     private fun setShowPlayedItemsMethod(item: MenuItem, showItems: ShowItems) { | ||||
|         showPlayedItems = showItems | ||||
|         viewModel.togglePlayedItems(showPlayedItems) | ||||
|         updateTogglePlayedItemsButton(item) | ||||
|         viewModel.saveShowPlayedItemsToPreferences(showPlayedItems) | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyOptionsMenu() { | ||||
|         super.onDestroyOptionsMenu() | ||||
|         activity?.supportActionBar?.subtitle = null | ||||
| @@ -284,19 +292,9 @@ class FeedFragment : BaseStateFragment<FeedState>() { | ||||
|     } | ||||
|  | ||||
|     private fun updateTogglePlayedItemsButton(menuItem: MenuItem) { | ||||
|         menuItem.isChecked = showPlayedItems | ||||
|         menuItem.icon = AppCompatResources.getDrawable( | ||||
|             requireContext(), | ||||
|             if (showPlayedItems) R.drawable.ic_visibility_on else R.drawable.ic_visibility_off | ||||
|         ) | ||||
|         MenuItemCompat.setTooltipText( | ||||
|             menuItem, | ||||
|             getString( | ||||
|                 if (showPlayedItems) | ||||
|                     R.string.feed_toggle_hide_played_items | ||||
|                 else | ||||
|                     R.string.feed_toggle_show_played_items | ||||
|             ) | ||||
|             getString(R.string.feed_toggle_show_hide_played_items) | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -28,15 +28,18 @@ 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: Boolean = true, | ||||
|     initialShowPlayedItems: ShowItems = ShowItems.DEFAULT, | ||||
|     initialShowFutureItems: Boolean = true | ||||
| ) : ViewModel() { | ||||
|     private val feedDatabaseManager = FeedDatabaseManager(application) | ||||
|  | ||||
|     private val toggleShowPlayedItems = BehaviorProcessor.create<Boolean>() | ||||
|     private val toggleShowPlayedItems = BehaviorProcessor.create<ShowItems>() | ||||
|     private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems | ||||
|         .startWithItem(initialShowPlayedItems) | ||||
|         .distinctUntilChanged() | ||||
| @@ -57,7 +60,7 @@ class FeedViewModel( | ||||
|             feedDatabaseManager.notLoadedCount(groupId), | ||||
|             feedDatabaseManager.oldestSubscriptionUpdate(groupId), | ||||
|  | ||||
|             Function5 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean, | ||||
|             Function5 { t1: FeedEventManager.Event, t2: ShowItems, t3: Boolean, | ||||
|                 t4: Long, t5: List<OffsetDateTime> -> | ||||
|                 return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull()) | ||||
|             } | ||||
| @@ -66,12 +69,21 @@ class FeedViewModel( | ||||
|         .subscribeOn(Schedulers.io()) | ||||
|         .observeOn(Schedulers.io()) | ||||
|         .map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) -> | ||||
|             val streamItems = if (event is SuccessResultEvent || event is IdleEvent) | ||||
|             val streamItems = if (event is SuccessResultEvent || event is IdleEvent) { | ||||
|                 feedDatabaseManager | ||||
|                     .getStreams(groupId, showPlayedItems, showFutureItems) | ||||
|                     .getStreams( | ||||
|                         groupId, | ||||
|                         !( | ||||
|                             showPlayedItems == ShowItems.WATCHED || | ||||
|                                 showPlayedItems == ShowItems.PARTIALLY_WATCHED | ||||
|                             ), | ||||
|                         showPlayedItems != ShowItems.PARTIALLY_WATCHED, | ||||
|                         showFutureItems | ||||
|                     ) | ||||
|                     .blockingGet(arrayListOf()) | ||||
|             else | ||||
|             } else { | ||||
|                 arrayListOf() | ||||
|             } | ||||
|  | ||||
|             CombineResultDataHolder(event, streamItems, notLoadedCount, oldestUpdate) | ||||
|         } | ||||
| @@ -98,7 +110,7 @@ class FeedViewModel( | ||||
|  | ||||
|     private data class CombineResultEventHolder( | ||||
|         val t1: FeedEventManager.Event, | ||||
|         val t2: Boolean, | ||||
|         val t2: ShowItems, | ||||
|         val t3: Boolean, | ||||
|         val t4: Long, | ||||
|         val t5: OffsetDateTime? | ||||
| @@ -111,17 +123,20 @@ class FeedViewModel( | ||||
|         val t4: OffsetDateTime? | ||||
|     ) | ||||
|  | ||||
|     fun togglePlayedItems(showPlayedItems: Boolean) { | ||||
|         toggleShowPlayedItems.onNext(showPlayedItems) | ||||
|     fun togglePlayedItems(showItems: ShowItems) { | ||||
|         toggleShowPlayedItems.onNext(showItems) | ||||
|     } | ||||
|  | ||||
|     fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) = | ||||
|     fun saveShowPlayedItemsToPreferences(showItems: ShowItems) = | ||||
|         PreferenceManager.getDefaultSharedPreferences(application).edit { | ||||
|             this.putBoolean(application.getString(R.string.feed_show_played_items_key), showPlayedItems) | ||||
|             this.putString( | ||||
|                 application.getString(R.string.feed_show_played_items_key), | ||||
|                 showItems.toString() | ||||
|             ) | ||||
|             this.apply() | ||||
|         } | ||||
|  | ||||
|     fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(application) | ||||
|     fun getItemsVisibilityFromPreferences() = getItemsVisibilityFromPreferences(application) | ||||
|  | ||||
|     fun toggleFutureItems(showFutureItems: Boolean) { | ||||
|         toggleShowFutureItems.onNext(showFutureItems) | ||||
| @@ -136,9 +151,16 @@ class FeedViewModel( | ||||
|     fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(application) | ||||
|  | ||||
|     companion object { | ||||
|         private fun getShowPlayedItemsFromPreferences(context: Context) = | ||||
|             PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getBoolean(context.getString(R.string.feed_show_played_items_key), true) | ||||
|  | ||||
|         private fun getItemsVisibilityFromPreferences(context: Context): ShowItems { | ||||
|             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) | ||||
|         } | ||||
|  | ||||
|         private fun getShowFutureItemsFromPreferences(context: Context) = | ||||
|             PreferenceManager.getDefaultSharedPreferences(context) | ||||
|                 .getBoolean(context.getString(R.string.feed_show_future_items_key), true) | ||||
| @@ -148,7 +170,7 @@ class FeedViewModel( | ||||
|                     App.getApp(), | ||||
|                     groupId, | ||||
|                     // Read initial value from preferences | ||||
|                     getShowPlayedItemsFromPreferences(context.applicationContext), | ||||
|                     getItemsVisibilityFromPreferences(context.applicationContext), | ||||
|                     getShowFutureItemsFromPreferences(context.applicationContext) | ||||
|                 ) | ||||
|             } | ||||
|   | ||||
| @@ -4,12 +4,23 @@ | ||||
|  | ||||
|     <item | ||||
|         android:id="@+id/menu_item_feed_toggle_played_items" | ||||
|         android:orderInCategory="2" | ||||
|         android:checkable="true" | ||||
|         android:checked="true" | ||||
|         android:checkable="false" | ||||
|         android:checked="false" | ||||
|         android:icon="@drawable/ic_visibility_on" | ||||
|         android:title="@string/feed_toggle_show_played_items" | ||||
|         app:showAsAction="ifRoom" /> | ||||
|         android:title="@string/feed_toggle_show_hide_played_items" | ||||
|         app:showAsAction="ifRoom"> | ||||
|         <menu> | ||||
|             <item | ||||
|                 android:id="@+id/menu_item_feed_toggle_show_all_items" | ||||
|                 android:title="@string/feed_toggle_show_items"/> | ||||
|             <item | ||||
|                 android:id="@+id/menu_item_feed_toggle_show_played_items" | ||||
|                 android:title="@string/feed_toggle_show_watched_items"/> | ||||
|             <item | ||||
|                 android:id="@+id/menu_item_feed_toggle_partially_played_items" | ||||
|                 android:title="@string/feed_toggle_show_partially_watched_items"/> | ||||
|         </menu> | ||||
|     </item> | ||||
|  | ||||
|     <item | ||||
|         android:id="@+id/menu_item_feed_toggle_future_items" | ||||
|   | ||||
| @@ -283,7 +283,7 @@ | ||||
|  | ||||
|     <string name="feed_update_threshold_key">feed_update_threshold_key</string> | ||||
|     <string name="feed_update_threshold_default_value">300</string> | ||||
|     <string name="feed_show_played_items_key">feed_show_played_items</string> | ||||
|     <string name="feed_show_played_items_key">feed_show_items</string> | ||||
|     <string name="feed_show_future_items_key">feed_show_future_items</string> | ||||
|  | ||||
|     <string name="show_thumbnail_key">show_thumbnail_key</string> | ||||
|   | ||||
| @@ -691,8 +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.</string> | ||||
|     <string name="feed_toggle_show_played_items">Show watched items</string> | ||||
|     <string name="feed_toggle_hide_played_items">Hide watched items</string> | ||||
|     <string name="feed_toggle_show_hide_played_items">Show/hide watched items</string> | ||||
|     <string name="content_not_supported">This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version.</string> | ||||
|     <string name="detail_sub_channel_thumbnail_view_description">Channel\'s avatar thumbnail</string> | ||||
|     <string name="channel_created_by">Created by %s</string> | ||||
| @@ -760,5 +759,8 @@ | ||||
|     <string name="unknown_quality">Unknown quality</string> | ||||
|     <string name="feed_toggle_show_future_items">Show future items</string> | ||||
|     <string name="feed_toggle_hide_future_items">Hide future items</string> | ||||
|     <string name="feed_toggle_show_partially_watched_items">Hide Watched and Partially Watched </string> | ||||
|     <string name="feed_toggle_show_watched_items">Hide Watched</string> | ||||
|     <string name="feed_toggle_show_items">Show All</string> | ||||
|     <string name="sort">Sort</string> | ||||
| </resources> | ||||
							
								
								
									
										1
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,5 @@ | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip | ||||
| distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4 | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jared Fantaye
					Jared Fantaye