mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 00:20:32 +00:00
Implemented the feature using multiple checkboxes
This commit is contained in:
parent
9c82441c19
commit
cd8d57040c
@ -73,6 +73,8 @@ abstract class FeedDAO {
|
||||
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 >= s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS}
|
||||
OR sst.progress_time >= s.duration * 1000 * 3 / 4)
|
||||
)
|
||||
AND (
|
||||
:uploadDateBefore IS NULL
|
||||
|
@ -37,7 +37,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.math.MathUtils
|
||||
import androidx.core.os.bundleOf
|
||||
@ -100,13 +99,10 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
private var oldestSubscriptionUpdate: OffsetDateTime? = null
|
||||
|
||||
private lateinit var groupAdapter: GroupieAdapter
|
||||
@State @JvmField var feedVisibilityStatus: StreamVisibilityStatus = StreamVisibilityStatus.DEFAULT
|
||||
@State @JvmField var showPlayedItems: Boolean = true
|
||||
@State @JvmField var showPartiallyPlayedItems: Boolean = true
|
||||
@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
|
||||
@ -144,7 +140,8 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
|
||||
val factory = FeedViewModel.getFactory(requireContext(), groupId)
|
||||
viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java]
|
||||
feedVisibilityStatus = viewModel.getItemsVisibilityFromPreferences()
|
||||
showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
|
||||
showPartiallyPlayedItems = viewModel.getShowPartiallyPlayedItemsFromPreferences()
|
||||
showFutureItems = viewModel.getShowFutureItemsFromPreferences()
|
||||
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) }
|
||||
|
||||
@ -220,16 +217,10 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
activity.supportActionBar?.subtitle = groupName
|
||||
|
||||
inflater.inflate(R.menu.menu_feed_fragment, menu)
|
||||
|
||||
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))
|
||||
MenuItemCompat.setTooltipText(
|
||||
menu.findItem(R.id.menu_item_feed_toggle_played_items),
|
||||
getString(R.string.feed_show_hide_streams)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
@ -254,27 +245,44 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
.create()
|
||||
.show()
|
||||
return true
|
||||
} else if (item.itemId == R.id.menu_item_feed_toggle_show_all_items) {
|
||||
changeItemsVisibilityStatus(item, StreamVisibilityStatus.DEFAULT)
|
||||
} else if (item.itemId == R.id.menu_item_feed_toggle_show_played_items) {
|
||||
changeItemsVisibilityStatus(item, StreamVisibilityStatus.HIDE_WATCHED)
|
||||
} else if (item.itemId == R.id.menu_item_feed_toggle_partially_played_items) {
|
||||
changeItemsVisibilityStatus(item, StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED)
|
||||
} else if (item.itemId == R.id.menu_item_feed_toggle_future_items) {
|
||||
showFutureItems = !item.isChecked
|
||||
updateToggleFutureItemsButton(item)
|
||||
viewModel.toggleFutureItems(showFutureItems)
|
||||
viewModel.saveShowFutureItemsToPreferences(showFutureItems)
|
||||
} else if (item.itemId == R.id.menu_item_feed_toggle_played_items) {
|
||||
showStreamVisibilityDialog()
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun changeItemsVisibilityStatus(item: MenuItem, streamVisibilityStatus: StreamVisibilityStatus) {
|
||||
feedVisibilityStatus = streamVisibilityStatus
|
||||
viewModel.changeVisibilityState(feedVisibilityStatus)
|
||||
updateItemVisibilityMenu(item)
|
||||
viewModel.saveStreamVisibilityStateToPreferences(feedVisibilityStatus)
|
||||
private fun showStreamVisibilityDialog() {
|
||||
val dialogItems = arrayOf(
|
||||
getString(R.string.feed_show_watched),
|
||||
getString(R.string.feed_show_partially_watched),
|
||||
getString(R.string.feed_show_upcoming)
|
||||
)
|
||||
|
||||
val checkedDialogItems = booleanArrayOf(!showPlayedItems, !showPartiallyPlayedItems, !showFutureItems)
|
||||
|
||||
val builder = AlertDialog.Builder(context!!)
|
||||
builder.setTitle(R.string.feed_hide_streams_title)
|
||||
builder.setMultiChoiceItems(dialogItems, checkedDialogItems) { _, which, isChecked ->
|
||||
checkedDialogItems[which] = isChecked
|
||||
}
|
||||
|
||||
builder.setPositiveButton(R.string.ok) { _, _ ->
|
||||
showPlayedItems = !checkedDialogItems[0]
|
||||
viewModel.setShowPlayedItems(showPlayedItems)
|
||||
viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
|
||||
|
||||
showPartiallyPlayedItems = !checkedDialogItems[1]
|
||||
viewModel.setShowPartiallyPlayedItems(showPartiallyPlayedItems)
|
||||
viewModel.saveShowPartiallyPlayedItemsToPreferences(showPartiallyPlayedItems)
|
||||
|
||||
showFutureItems = !checkedDialogItems[2]
|
||||
viewModel.setShowFutureItems(showFutureItems)
|
||||
viewModel.saveShowFutureItemsToPreferences(showFutureItems)
|
||||
}
|
||||
builder.setNegativeButton(R.string.cancel, null)
|
||||
|
||||
builder.create().show()
|
||||
}
|
||||
|
||||
override fun onDestroyOptionsMenu() {
|
||||
@ -303,48 +311,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
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_change_stream_visibility_state)
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
MenuItemCompat.setTooltipText(
|
||||
menuItem,
|
||||
getString(
|
||||
if (showFutureItems)
|
||||
R.string.feed_toggle_hide_future_items
|
||||
else
|
||||
R.string.feed_toggle_show_future_items
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////
|
||||
// Handling
|
||||
// //////////////////////////////////////////////////////////////////////////
|
||||
|
@ -11,7 +11,7 @@ import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import androidx.preference.PreferenceManager
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.functions.Function5
|
||||
import io.reactivex.rxjava3.functions.Function6
|
||||
import io.reactivex.rxjava3.processors.BehaviorProcessor
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.schabi.newpipe.App
|
||||
@ -31,18 +31,24 @@ import java.util.concurrent.TimeUnit
|
||||
class FeedViewModel(
|
||||
private val application: Application,
|
||||
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
|
||||
initialStreamVisibility: StreamVisibilityStatus = StreamVisibilityStatus.DEFAULT,
|
||||
initialShowPlayedItems: Boolean = true,
|
||||
initialShowPartiallyPlayedItems: Boolean = true,
|
||||
initialShowFutureItems: Boolean = true
|
||||
) : ViewModel() {
|
||||
private val feedDatabaseManager = FeedDatabaseManager(application)
|
||||
|
||||
private val streamVisibilityState = BehaviorProcessor.create<StreamVisibilityStatus>()
|
||||
private val streamVisibilityStateFlowable = streamVisibilityState
|
||||
.startWithItem(initialStreamVisibility)
|
||||
private val showPlayedItems = BehaviorProcessor.create<Boolean>()
|
||||
private val showPlayedItemsFlowable = showPlayedItems
|
||||
.startWithItem(initialShowPlayedItems)
|
||||
.distinctUntilChanged()
|
||||
|
||||
private val toggleShowFutureItems = BehaviorProcessor.create<Boolean>()
|
||||
private val toggleShowFutureItemsFlowable = toggleShowFutureItems
|
||||
private val showPartiallyPlayedItems = BehaviorProcessor.create<Boolean>()
|
||||
private val showPartiallyPlayedItemsFlowable = showPartiallyPlayedItems
|
||||
.startWithItem(initialShowPartiallyPlayedItems)
|
||||
.distinctUntilChanged()
|
||||
|
||||
private val showFutureItems = BehaviorProcessor.create<Boolean>()
|
||||
private val showFutureItemsFlowable = showFutureItems
|
||||
.startWithItem(initialShowFutureItems)
|
||||
.distinctUntilChanged()
|
||||
|
||||
@ -52,35 +58,27 @@ class FeedViewModel(
|
||||
private var combineDisposable = Flowable
|
||||
.combineLatest(
|
||||
FeedEventManager.events(),
|
||||
streamVisibilityStateFlowable,
|
||||
toggleShowFutureItemsFlowable,
|
||||
showPlayedItemsFlowable,
|
||||
showPartiallyPlayedItemsFlowable,
|
||||
showFutureItemsFlowable,
|
||||
feedDatabaseManager.notLoadedCount(groupId),
|
||||
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
|
||||
|
||||
Function5 { t1: FeedEventManager.Event, t2: StreamVisibilityStatus, t3: Boolean,
|
||||
t4: Long, t5: List<OffsetDateTime> ->
|
||||
return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull())
|
||||
Function6 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean, t4: Boolean,
|
||||
t5: Long, t6: List<OffsetDateTime> ->
|
||||
return@Function6 CombineResultEventHolder(t1, t2, t3, t4, t5, t6.firstOrNull())
|
||||
}
|
||||
)
|
||||
.throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
|
||||
val streamItems = if (event is SuccessResultEvent || event is IdleEvent) {
|
||||
.map { (event, showPlayedItems, showPartiallyPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
|
||||
val streamItems = if (event is SuccessResultEvent || event is IdleEvent)
|
||||
feedDatabaseManager
|
||||
.getStreams(
|
||||
groupId,
|
||||
!(
|
||||
showPlayedItems == StreamVisibilityStatus.HIDE_WATCHED ||
|
||||
showPlayedItems == StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED
|
||||
),
|
||||
showPlayedItems != StreamVisibilityStatus.HIDE_PARTIALLY_WATCHED,
|
||||
showFutureItems
|
||||
)
|
||||
.getStreams(groupId, showPlayedItems, showPartiallyPlayedItems, showFutureItems)
|
||||
.blockingGet(arrayListOf())
|
||||
} else {
|
||||
else
|
||||
arrayListOf()
|
||||
}
|
||||
|
||||
CombineResultDataHolder(event, streamItems, notLoadedCount, oldestUpdate)
|
||||
}
|
||||
@ -107,10 +105,11 @@ class FeedViewModel(
|
||||
|
||||
private data class CombineResultEventHolder(
|
||||
val t1: FeedEventManager.Event,
|
||||
val t2: StreamVisibilityStatus,
|
||||
val t2: Boolean,
|
||||
val t3: Boolean,
|
||||
val t4: Long,
|
||||
val t5: OffsetDateTime?
|
||||
val t4: Boolean,
|
||||
val t5: Long,
|
||||
val t6: OffsetDateTime?
|
||||
)
|
||||
|
||||
private data class CombineResultDataHolder(
|
||||
@ -120,23 +119,32 @@ class FeedViewModel(
|
||||
val t4: OffsetDateTime?
|
||||
)
|
||||
|
||||
fun changeVisibilityState(streamVisibilityStatus: StreamVisibilityStatus) {
|
||||
streamVisibilityState.onNext(streamVisibilityStatus)
|
||||
fun setShowPlayedItems(showPlayedItems: Boolean) {
|
||||
this.showPlayedItems.onNext(showPlayedItems)
|
||||
}
|
||||
|
||||
fun saveStreamVisibilityStateToPreferences(streamVisibilityStatus: StreamVisibilityStatus) =
|
||||
fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) =
|
||||
PreferenceManager.getDefaultSharedPreferences(application).edit {
|
||||
this.putString(
|
||||
application.getString(R.string.feed_stream_visibility_state_key),
|
||||
streamVisibilityStatus.toString()
|
||||
)
|
||||
this.putBoolean(application.getString(R.string.feed_show_watched_items_key), showPlayedItems)
|
||||
this.apply()
|
||||
}
|
||||
|
||||
fun getItemsVisibilityFromPreferences() = getStreamVisibilityStateFromPreferences(application)
|
||||
fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(application)
|
||||
|
||||
fun toggleFutureItems(showFutureItems: Boolean) {
|
||||
toggleShowFutureItems.onNext(showFutureItems)
|
||||
fun setShowPartiallyPlayedItems(showPartiallyPlayedItems: Boolean) {
|
||||
this.showPartiallyPlayedItems.onNext(showPartiallyPlayedItems)
|
||||
}
|
||||
|
||||
fun saveShowPartiallyPlayedItemsToPreferences(showPartiallyPlayedItems: Boolean) =
|
||||
PreferenceManager.getDefaultSharedPreferences(application).edit {
|
||||
this.putBoolean(application.getString(R.string.feed_show_partially_watched_items_key), showPartiallyPlayedItems)
|
||||
this.apply()
|
||||
}
|
||||
|
||||
fun getShowPartiallyPlayedItemsFromPreferences() = getShowPartiallyPlayedItemsFromPreferences(application)
|
||||
|
||||
fun setShowFutureItems(showFutureItems: Boolean) {
|
||||
this.showFutureItems.onNext(showFutureItems)
|
||||
}
|
||||
|
||||
fun saveShowFutureItemsToPreferences(showFutureItems: Boolean) =
|
||||
@ -148,16 +156,13 @@ class FeedViewModel(
|
||||
fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(application)
|
||||
|
||||
companion object {
|
||||
private fun getShowPlayedItemsFromPreferences(context: Context) =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(context.getString(R.string.feed_show_watched_items_key), true)
|
||||
|
||||
private fun getStreamVisibilityStateFromPreferences(context: Context): StreamVisibilityStatus {
|
||||
val s = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getString(
|
||||
context.getString(R.string.feed_stream_visibility_state_key),
|
||||
StreamVisibilityStatus.DEFAULT.toString()
|
||||
) ?: StreamVisibilityStatus.DEFAULT.toString()
|
||||
return StreamVisibilityStatus.valueOf(s)
|
||||
}
|
||||
|
||||
private fun getShowPartiallyPlayedItemsFromPreferences(context: Context) =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(context.getString(R.string.feed_show_partially_watched_items_key), true)
|
||||
private fun getShowFutureItemsFromPreferences(context: Context) =
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getBoolean(context.getString(R.string.feed_show_future_items_key), true)
|
||||
@ -167,7 +172,8 @@ class FeedViewModel(
|
||||
App.getApp(),
|
||||
groupId,
|
||||
// Read initial value from preferences
|
||||
getStreamVisibilityStateFromPreferences(context.applicationContext),
|
||||
getShowPlayedItemsFromPreferences(context.applicationContext),
|
||||
getShowPartiallyPlayedItemsFromPreferences(context.applicationContext),
|
||||
getShowFutureItemsFromPreferences(context.applicationContext)
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package org.schabi.newpipe.local.feed
|
||||
|
||||
enum class StreamVisibilityStatus {
|
||||
DEFAULT, HIDE_WATCHED, HIDE_PARTIALLY_WATCHED
|
||||
}
|
@ -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#changeVisibilityState
|
||||
* @see FeedViewModel#setShowPlayedItems
|
||||
* @param info the item to mark as watched
|
||||
* @return a Maybe containing the ID of the item if successful
|
||||
*/
|
||||
|
@ -4,31 +4,9 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_item_feed_toggle_played_items"
|
||||
android:checkable="false"
|
||||
android:checked="false"
|
||||
android:orderInCategory="2"
|
||||
android:icon="@drawable/ic_visibility_on"
|
||||
android:title="@string/feed_change_stream_visibility_state"
|
||||
app:showAsAction="ifRoom">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/menu_item_feed_toggle_show_all_items"
|
||||
android:title="@string/feed_stream_visibility_show_all"/>
|
||||
<item
|
||||
android:id="@+id/menu_item_feed_toggle_show_played_items"
|
||||
android:title="@string/feed_stream_visibility_hide_watched"/>
|
||||
<item
|
||||
android:id="@+id/menu_item_feed_toggle_partially_played_items"
|
||||
android:title="@string/feed_stream_visibility_hide_partially_watched"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<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"
|
||||
android:title="@string/feed_show_hide_streams"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
|
@ -283,7 +283,8 @@
|
||||
|
||||
<string name="feed_update_threshold_key">feed_update_threshold_key</string>
|
||||
<string name="feed_update_threshold_default_value">300</string>
|
||||
<string name="feed_stream_visibility_state_key">feed_stream_visibility_state</string>
|
||||
<string name="feed_show_watched_items_key">feed_show_watched_items</string>
|
||||
<string name="feed_show_partially_watched_items_key">feed_show_partially_watched_items</string>
|
||||
<string name="feed_show_future_items_key">feed_show_future_items</string>
|
||||
|
||||
<string name="show_thumbnail_key">show_thumbnail_key</string>
|
||||
|
@ -691,7 +691,8 @@
|
||||
\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_change_stream_visibility_state">Show/hide watched streams</string>
|
||||
<string name="feed_hide_streams_title">Hide the following streams</string>
|
||||
<string name="feed_show_hide_streams">Show/Hide streams</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>
|
||||
@ -759,8 +760,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_stream_visibility_hide_partially_watched">Hide Watched </string>
|
||||
<string name="feed_stream_visibility_hide_watched">Hide Fully Watched</string>
|
||||
<string name="feed_stream_visibility_show_all">Show All</string>
|
||||
<string name="feed_show_watched">Fully Watched</string>
|
||||
<string name="feed_show_partially_watched">Partially Watched</string>
|
||||
<string name="feed_show_upcoming">Upcoming</string>
|
||||
<string name="sort">Sort</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user