Merge pull request #8545 from carmebar/hide-future-videos

Add option to hide future videos in feed
This commit is contained in:
Stypox 2022-07-13 11:07:38 +02:00 committed by GitHub
commit b96c8a0c2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 10 deletions

View file

@ -98,6 +98,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
private lateinit var groupAdapter: GroupieAdapter private lateinit var groupAdapter: GroupieAdapter
@State @JvmField var showPlayedItems: Boolean = true @State @JvmField var showPlayedItems: Boolean = true
@State @JvmField var showFutureItems: Boolean = true
private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null
private var updateListViewModeOnResume = false private var updateListViewModeOnResume = false
@ -137,6 +138,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
val factory = FeedViewModel.Factory(requireContext(), groupId) val factory = FeedViewModel.Factory(requireContext(), groupId)
viewModel = ViewModelProvider(this, factory).get(FeedViewModel::class.java) viewModel = ViewModelProvider(this, factory).get(FeedViewModel::class.java)
showPlayedItems = viewModel.getShowPlayedItemsFromPreferences() showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
showFutureItems = viewModel.getShowFutureItemsFromPreferences()
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) } viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) }
groupAdapter = GroupieAdapter().apply { groupAdapter = GroupieAdapter().apply {
@ -212,6 +214,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
inflater.inflate(R.menu.menu_feed_fragment, menu) inflater.inflate(R.menu.menu_feed_fragment, menu)
updateTogglePlayedItemsButton(menu.findItem(R.id.menu_item_feed_toggle_played_items)) updateTogglePlayedItemsButton(menu.findItem(R.id.menu_item_feed_toggle_played_items))
updateToggleFutureItemsButton(menu.findItem(R.id.menu_item_feed_toggle_future_items))
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -241,6 +244,11 @@ class FeedFragment : BaseStateFragment<FeedState>() {
updateTogglePlayedItemsButton(item) updateTogglePlayedItemsButton(item)
viewModel.togglePlayedItems(showPlayedItems) viewModel.togglePlayedItems(showPlayedItems)
viewModel.saveShowPlayedItemsToPreferences(showPlayedItems) viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
} else if (item.itemId == R.id.menu_item_feed_toggle_future_items) {
showFutureItems = !item.isChecked
updateToggleFutureItemsButton(item)
viewModel.toggleFutureItems(showFutureItems)
viewModel.saveShowFutureItemsToPreferences(showFutureItems)
} }
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
@ -280,6 +288,14 @@ class FeedFragment : BaseStateFragment<FeedState>() {
) )
} }
private fun updateToggleFutureItemsButton(menuItem: MenuItem) {
menuItem.isChecked = showFutureItems
menuItem.icon = AppCompatResources.getDrawable(
requireContext(),
if (showFutureItems) R.drawable.ic_history_future else R.drawable.ic_history
)
}
// ////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////
// Handling // Handling
// ////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////

View file

@ -9,7 +9,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.functions.Function4 import io.reactivex.rxjava3.functions.Function5
import io.reactivex.rxjava3.processors.BehaviorProcessor import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.R import org.schabi.newpipe.R
@ -28,7 +28,8 @@ import java.util.concurrent.TimeUnit
class FeedViewModel( class FeedViewModel(
private val applicationContext: Context, private val applicationContext: Context,
groupId: Long = FeedGroupEntity.GROUP_ALL_ID, groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
initialShowPlayedItems: Boolean = true initialShowPlayedItems: Boolean = true,
initialShowFutureItems: Boolean = true
) : ViewModel() { ) : ViewModel() {
private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(applicationContext) private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(applicationContext)
@ -37,6 +38,11 @@ class FeedViewModel(
.startWithItem(initialShowPlayedItems) .startWithItem(initialShowPlayedItems)
.distinctUntilChanged() .distinctUntilChanged()
private val toggleShowFutureItems = BehaviorProcessor.create<Boolean>()
private val toggleShowFutureItemsFlowable = toggleShowFutureItems
.startWithItem(initialShowFutureItems)
.distinctUntilChanged()
private val mutableStateLiveData = MutableLiveData<FeedState>() private val mutableStateLiveData = MutableLiveData<FeedState>()
val stateLiveData: LiveData<FeedState> = mutableStateLiveData val stateLiveData: LiveData<FeedState> = mutableStateLiveData
@ -44,22 +50,24 @@ class FeedViewModel(
.combineLatest( .combineLatest(
FeedEventManager.events(), FeedEventManager.events(),
toggleShowPlayedItemsFlowable, toggleShowPlayedItemsFlowable,
toggleShowFutureItemsFlowable,
feedDatabaseManager.notLoadedCount(groupId), feedDatabaseManager.notLoadedCount(groupId),
feedDatabaseManager.oldestSubscriptionUpdate(groupId), feedDatabaseManager.oldestSubscriptionUpdate(groupId),
Function4 { t1: FeedEventManager.Event, t2: Boolean, Function5 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean,
t3: Long, t4: List<OffsetDateTime> -> t4: Long, t5: List<OffsetDateTime> ->
return@Function4 CombineResultEventHolder(t1, t2, t3, t4.firstOrNull()) return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull())
} }
) )
.throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.map { (event, showPlayedItems, notLoadedCount, oldestUpdate) -> .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 feedDatabaseManager
.getStreams(groupId, showPlayedItems) .getStreams(groupId, showPlayedItems)
.blockingGet(arrayListOf()) .blockingGet(arrayListOf())
.filter { s -> showFutureItems || s.stream.uploadDate?.isBefore(OffsetDateTime.now()) ?: true }
else else
arrayListOf() arrayListOf()
@ -89,8 +97,9 @@ class FeedViewModel(
private data class CombineResultEventHolder( private data class CombineResultEventHolder(
val t1: FeedEventManager.Event, val t1: FeedEventManager.Event,
val t2: Boolean, val t2: Boolean,
val t3: Long, val t3: Boolean,
val t4: OffsetDateTime? val t4: Long,
val t5: OffsetDateTime?
) )
private data class CombineResultDataHolder( private data class CombineResultDataHolder(
@ -112,10 +121,25 @@ class FeedViewModel(
fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(applicationContext) fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(applicationContext)
fun toggleFutureItems(showFutureItems: Boolean) {
toggleShowFutureItems.onNext(showFutureItems)
}
fun saveShowFutureItemsToPreferences(showFutureItems: Boolean) =
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit {
this.putBoolean(applicationContext.getString(R.string.feed_show_future_items_key), showFutureItems)
this.apply()
}
fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(applicationContext)
companion object { companion object {
private fun getShowPlayedItemsFromPreferences(context: Context) = private fun getShowPlayedItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context) PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_played_items_key), true) .getBoolean(context.getString(R.string.feed_show_played_items_key), true)
private fun getShowFutureItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_future_items_key), true)
} }
class Factory( class Factory(
@ -128,7 +152,8 @@ class FeedViewModel(
context.applicationContext, context.applicationContext,
groupId, groupId,
// Read initial value from preferences // Read initial value from preferences
getShowPlayedItemsFromPreferences(context.applicationContext) getShowPlayedItemsFromPreferences(context.applicationContext),
getShowFutureItemsFromPreferences(context.applicationContext)
) as T ) as T
} }
} }

View file

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@color/defaultIconTint"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="flip"
android:pivotX="12"
android:scaleX="-1">
<path
android:fillColor="#FF000000"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" />
</group>
</vector>

View file

@ -11,10 +11,19 @@
android:title="@string/feed_toggle_show_played_items" android:title="@string/feed_toggle_show_played_items"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_item_feed_toggle_future_items"
android:orderInCategory="3"
android:checkable="true"
android:checked="true"
android:icon="@drawable/ic_history_future"
android:title="@string/feed_toggle_show_future_items"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/menu_item_feed_help" android:id="@+id/menu_item_feed_help"
android:icon="@drawable/ic_help" android:icon="@drawable/ic_help"
android:title="@string/help" android:title="@string/help"
android:orderInCategory="3" android:orderInCategory="4"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
</menu> </menu>

View file

@ -284,6 +284,7 @@
<string name="feed_update_threshold_key">feed_update_threshold_key</string> <string name="feed_update_threshold_key">feed_update_threshold_key</string>
<string name="feed_update_threshold_default_value">300</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_played_items</string>
<string name="feed_show_future_items_key">feed_show_future_items</string>
<string name="show_thumbnail_key">show_thumbnail_key</string> <string name="show_thumbnail_key">show_thumbnail_key</string>

View file

@ -747,4 +747,5 @@
<string name="select_quality_external_players">Select quality for external players</string> <string name="select_quality_external_players">Select quality for external players</string>
<string name="unknown_format">Unknown format</string> <string name="unknown_format">Unknown format</string>
<string name="unknown_quality">Unknown quality</string> <string name="unknown_quality">Unknown quality</string>
<string name="feed_toggle_show_future_items">Show future videos</string>
</resources> </resources>