Skip to content

Commit d2d324f

Browse files
committed
First draft of the new feature
1 parent fceec71 commit d2d324f

9 files changed

Lines changed: 87 additions & 44 deletions

File tree

app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ abstract class FeedDAO {
3232
* @return the feed streams filtered according to the conditions provided in the parameters
3333
* @see StreamStateEntity.isFinished()
3434
* @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS
35+
* @see StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS
3536
*/
3637
@Query(
3738
"""
@@ -66,6 +67,13 @@ abstract class FeedDAO {
6667
OR s.stream_type = 'LIVE_STREAM'
6768
OR s.stream_type = 'AUDIO_LIVE_STREAM'
6869
)
70+
AND (
71+
:includePartiallyPlayed
72+
OR sh.stream_id IS NULL
73+
OR sst.stream_id IS NULL
74+
OR (sst.progress_time < ${StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS}
75+
AND sst.progress_time < s.duration * 1000 / 4)
76+
)
6977
AND (
7078
:uploadDateBefore IS NULL
7179
OR s.upload_date IS NULL
@@ -79,6 +87,7 @@ abstract class FeedDAO {
7987
abstract fun getStreams(
8088
groupId: Long,
8189
includePlayed: Boolean,
90+
includePartiallyPlayed: Boolean,
8291
uploadDateBefore: OffsetDateTime?
8392
): Maybe<List<StreamWithState>>
8493

app/src/main/java/org/schabi/newpipe/database/stream/model/StreamStateEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class StreamStateEntity {
3030
/**
3131
* Playback state will not be saved, if playback time is less than this threshold (5000ms = 5s).
3232
*/
33-
private static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000;
33+
public static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000;
3434

3535
/**
3636
* Stream will be considered finished if the playback time left exceeds this threshold

app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ class FeedDatabaseManager(context: Context) {
4343
fun getStreams(
4444
groupId: Long,
4545
includePlayedStreams: Boolean,
46+
includePartiallyPlayedStreams: Boolean,
4647
includeFutureStreams: Boolean
4748
): Maybe<List<StreamWithState>> {
4849
return feedTable.getStreams(
4950
groupId,
5051
includePlayedStreams,
52+
includePartiallyPlayedStreams,
5153
if (includeFutureStreams) null else OffsetDateTime.now()
5254
)
5355
}

app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
100100
private var oldestSubscriptionUpdate: OffsetDateTime? = null
101101

102102
private lateinit var groupAdapter: GroupieAdapter
103-
@State @JvmField var showPlayedItems: Boolean = true
103+
@State @JvmField var showPlayedItems: ShowItems = ShowItems.DEFAULT
104104
@State @JvmField var showFutureItems: Boolean = true
105105

106106
private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null
@@ -140,7 +140,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
140140

141141
val factory = FeedViewModel.getFactory(requireContext(), groupId)
142142
viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java]
143-
showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
143+
showPlayedItems = viewModel.getItemsVisibilityFromPreferences()
144144
showFutureItems = viewModel.getShowFutureItemsFromPreferences()
145145
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) }
146146

@@ -242,11 +242,12 @@ class FeedFragment : BaseStateFragment<FeedState>() {
242242
.create()
243243
.show()
244244
return true
245-
} else if (item.itemId == R.id.menu_item_feed_toggle_played_items) {
246-
showPlayedItems = !item.isChecked
247-
updateTogglePlayedItemsButton(item)
248-
viewModel.togglePlayedItems(showPlayedItems)
249-
viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
245+
} else if (item.itemId == R.id.menu_item_feed_toggle_show_all_items) {
246+
setShowPlayedItemsMethod(item, ShowItems.DEFAULT)
247+
} else if (item.itemId == R.id.menu_item_feed_toggle_show_played_items) {
248+
setShowPlayedItemsMethod(item, ShowItems.WATCHED)
249+
} else if (item.itemId == R.id.menu_item_feed_toggle_partially_played_items) {
250+
setShowPlayedItemsMethod(item, ShowItems.PARTIALLY_WATCHED)
250251
} else if (item.itemId == R.id.menu_item_feed_toggle_future_items) {
251252
showFutureItems = !item.isChecked
252253
updateToggleFutureItemsButton(item)
@@ -257,6 +258,13 @@ class FeedFragment : BaseStateFragment<FeedState>() {
257258
return super.onOptionsItemSelected(item)
258259
}
259260

261+
private fun setShowPlayedItemsMethod(item: MenuItem, showItems: ShowItems) {
262+
showPlayedItems = showItems
263+
viewModel.togglePlayedItems(showPlayedItems)
264+
updateTogglePlayedItemsButton(item)
265+
viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
266+
}
267+
260268
override fun onDestroyOptionsMenu() {
261269
super.onDestroyOptionsMenu()
262270
activity?.supportActionBar?.subtitle = null
@@ -284,19 +292,9 @@ class FeedFragment : BaseStateFragment<FeedState>() {
284292
}
285293

286294
private fun updateTogglePlayedItemsButton(menuItem: MenuItem) {
287-
menuItem.isChecked = showPlayedItems
288-
menuItem.icon = AppCompatResources.getDrawable(
289-
requireContext(),
290-
if (showPlayedItems) R.drawable.ic_visibility_on else R.drawable.ic_visibility_off
291-
)
292295
MenuItemCompat.setTooltipText(
293296
menuItem,
294-
getString(
295-
if (showPlayedItems)
296-
R.string.feed_toggle_hide_played_items
297-
else
298-
R.string.feed_toggle_show_played_items
299-
)
297+
getString(R.string.feed_toggle_show_hide_played_items)
300298
)
301299
}
302300

app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,18 @@ import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT
2828
import java.time.OffsetDateTime
2929
import java.util.concurrent.TimeUnit
3030

31+
enum class ShowItems {
32+
WATCHED, PARTIALLY_WATCHED, DEFAULT
33+
}
3134
class FeedViewModel(
3235
private val application: Application,
3336
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
34-
initialShowPlayedItems: Boolean = true,
37+
initialShowPlayedItems: ShowItems = ShowItems.DEFAULT,
3538
initialShowFutureItems: Boolean = true
3639
) : ViewModel() {
3740
private val feedDatabaseManager = FeedDatabaseManager(application)
3841

39-
private val toggleShowPlayedItems = BehaviorProcessor.create<Boolean>()
42+
private val toggleShowPlayedItems = BehaviorProcessor.create<ShowItems>()
4043
private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems
4144
.startWithItem(initialShowPlayedItems)
4245
.distinctUntilChanged()
@@ -57,7 +60,7 @@ class FeedViewModel(
5760
feedDatabaseManager.notLoadedCount(groupId),
5861
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
5962

60-
Function5 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean,
63+
Function5 { t1: FeedEventManager.Event, t2: ShowItems, t3: Boolean,
6164
t4: Long, t5: List<OffsetDateTime> ->
6265
return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull())
6366
}
@@ -66,12 +69,21 @@ class FeedViewModel(
6669
.subscribeOn(Schedulers.io())
6770
.observeOn(Schedulers.io())
6871
.map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
69-
val streamItems = if (event is SuccessResultEvent || event is IdleEvent)
72+
val streamItems = if (event is SuccessResultEvent || event is IdleEvent) {
7073
feedDatabaseManager
71-
.getStreams(groupId, showPlayedItems, showFutureItems)
74+
.getStreams(
75+
groupId,
76+
!(
77+
showPlayedItems == ShowItems.WATCHED ||
78+
showPlayedItems == ShowItems.PARTIALLY_WATCHED
79+
),
80+
showPlayedItems != ShowItems.PARTIALLY_WATCHED,
81+
showFutureItems
82+
)
7283
.blockingGet(arrayListOf())
73-
else
84+
} else {
7485
arrayListOf()
86+
}
7587

7688
CombineResultDataHolder(event, streamItems, notLoadedCount, oldestUpdate)
7789
}
@@ -98,7 +110,7 @@ class FeedViewModel(
98110

99111
private data class CombineResultEventHolder(
100112
val t1: FeedEventManager.Event,
101-
val t2: Boolean,
113+
val t2: ShowItems,
102114
val t3: Boolean,
103115
val t4: Long,
104116
val t5: OffsetDateTime?
@@ -111,17 +123,20 @@ class FeedViewModel(
111123
val t4: OffsetDateTime?
112124
)
113125

114-
fun togglePlayedItems(showPlayedItems: Boolean) {
115-
toggleShowPlayedItems.onNext(showPlayedItems)
126+
fun togglePlayedItems(showItems: ShowItems) {
127+
toggleShowPlayedItems.onNext(showItems)
116128
}
117129

118-
fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) =
130+
fun saveShowPlayedItemsToPreferences(showItems: ShowItems) =
119131
PreferenceManager.getDefaultSharedPreferences(application).edit {
120-
this.putBoolean(application.getString(R.string.feed_show_played_items_key), showPlayedItems)
132+
this.putString(
133+
application.getString(R.string.feed_show_played_items_key),
134+
showItems.toString()
135+
)
121136
this.apply()
122137
}
123138

124-
fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(application)
139+
fun getItemsVisibilityFromPreferences() = getItemsVisibilityFromPreferences(application)
125140

126141
fun toggleFutureItems(showFutureItems: Boolean) {
127142
toggleShowFutureItems.onNext(showFutureItems)
@@ -136,9 +151,16 @@ class FeedViewModel(
136151
fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(application)
137152

138153
companion object {
139-
private fun getShowPlayedItemsFromPreferences(context: Context) =
140-
PreferenceManager.getDefaultSharedPreferences(context)
141-
.getBoolean(context.getString(R.string.feed_show_played_items_key), true)
154+
155+
private fun getItemsVisibilityFromPreferences(context: Context): ShowItems {
156+
val s = PreferenceManager.getDefaultSharedPreferences(context)
157+
.getString(
158+
context.getString(R.string.feed_show_played_items_key),
159+
ShowItems.DEFAULT.toString()
160+
) ?: ShowItems.DEFAULT.toString()
161+
return ShowItems.valueOf(s)
162+
}
163+
142164
private fun getShowFutureItemsFromPreferences(context: Context) =
143165
PreferenceManager.getDefaultSharedPreferences(context)
144166
.getBoolean(context.getString(R.string.feed_show_future_items_key), true)
@@ -148,7 +170,7 @@ class FeedViewModel(
148170
App.getApp(),
149171
groupId,
150172
// Read initial value from preferences
151-
getShowPlayedItemsFromPreferences(context.applicationContext),
173+
getItemsVisibilityFromPreferences(context.applicationContext),
152174
getShowFutureItemsFromPreferences(context.applicationContext)
153175
)
154176
}

app/src/main/res/menu/menu_feed_fragment.xml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,23 @@
44

55
<item
66
android:id="@+id/menu_item_feed_toggle_played_items"
7-
android:orderInCategory="2"
8-
android:checkable="true"
9-
android:checked="true"
7+
android:checkable="false"
8+
android:checked="false"
109
android:icon="@drawable/ic_visibility_on"
11-
android:title="@string/feed_toggle_show_played_items"
12-
app:showAsAction="ifRoom" />
10+
android:title="@string/feed_toggle_show_hide_played_items"
11+
app:showAsAction="ifRoom">
12+
<menu>
13+
<item
14+
android:id="@+id/menu_item_feed_toggle_show_all_items"
15+
android:title="@string/feed_toggle_show_items"/>
16+
<item
17+
android:id="@+id/menu_item_feed_toggle_show_played_items"
18+
android:title="@string/feed_toggle_show_watched_items"/>
19+
<item
20+
android:id="@+id/menu_item_feed_toggle_partially_played_items"
21+
android:title="@string/feed_toggle_show_partially_watched_items"/>
22+
</menu>
23+
</item>
1324

1425
<item
1526
android:id="@+id/menu_item_feed_toggle_future_items"

app/src/main/res/values/settings_keys.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283

284284
<string name="feed_update_threshold_key">feed_update_threshold_key</string>
285285
<string name="feed_update_threshold_default_value">300</string>
286-
<string name="feed_show_played_items_key">feed_show_played_items</string>
286+
<string name="feed_show_played_items_key">feed_show_items</string>
287287
<string name="feed_show_future_items_key">feed_show_future_items</string>
288288

289289
<string name="show_thumbnail_key">show_thumbnail_key</string>

app/src/main/res/values/strings.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,7 @@
691691
\nYouTube is an example of a service that offers this fast method with its RSS feed.
692692
\n
693693
\nSo the choice boils down to what you prefer: speed or precise information.</string>
694-
<string name="feed_toggle_show_played_items">Show watched items</string>
695-
<string name="feed_toggle_hide_played_items">Hide watched items</string>
694+
<string name="feed_toggle_show_hide_played_items">Show/hide watched items</string>
696695
<string name="content_not_supported">This content is not yet supported by NewPipe.\n\nIt will hopefully be supported in a future version.</string>
697696
<string name="detail_sub_channel_thumbnail_view_description">Channel\'s avatar thumbnail</string>
698697
<string name="channel_created_by">Created by %s</string>
@@ -760,5 +759,8 @@
760759
<string name="unknown_quality">Unknown quality</string>
761760
<string name="feed_toggle_show_future_items">Show future items</string>
762761
<string name="feed_toggle_hide_future_items">Hide future items</string>
762+
<string name="feed_toggle_show_partially_watched_items">Hide Watched and Partially Watched </string>
763+
<string name="feed_toggle_show_watched_items">Hide Watched</string>
764+
<string name="feed_toggle_show_items">Show All</string>
763765
<string name="sort">Sort</string>
764766
</resources>
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
4-
distributionSha256Sum=f6b8596b10cce501591e92f229816aa4046424f3b24d771751b06779d58c8ec4
54
zipStoreBase=GRADLE_USER_HOME
65
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)