First draft of the new feature
This commit is contained in:
parent
fceec71ad3
commit
d2d324f2dd
9 changed files with 87 additions and 44 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue