Merge pull request #5494 from Bnyro/master

feat: add 'hide watched videos' to feed filter options
This commit is contained in:
Bnyro 2024-01-15 18:01:04 +01:00 committed by GitHub
commit b1f21c2866
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 30 deletions

View File

@ -35,4 +35,5 @@ object IntentData {
const val isCurrentlyPlaying = "isCurrentlyPlaying" const val isCurrentlyPlaying = "isCurrentlyPlaying"
const val isSubscribed = "isSubscribed" const val isSubscribed = "isSubscribed"
const val sortOptions = "sortOptions" const val sortOptions = "sortOptions"
const val hideWatched = "hideWatched"
} }

View File

@ -40,7 +40,6 @@ import com.github.libretube.ui.models.SubscriptionsViewModel
import com.github.libretube.ui.sheets.ChannelGroupsSheet import com.github.libretube.ui.sheets.ChannelGroupsSheet
import com.github.libretube.ui.sheets.FilterSortBottomSheet import com.github.libretube.ui.sheets.FilterSortBottomSheet
import com.github.libretube.ui.sheets.FilterSortBottomSheet.Companion.FILTER_SORT_REQUEST_KEY import com.github.libretube.ui.sheets.FilterSortBottomSheet.Companion.FILTER_SORT_REQUEST_KEY
import com.github.libretube.ui.sheets.FilterSortBottomSheet.Companion.SELECTED_SORT_OPTION_KEY
import com.github.libretube.util.PlayingQueue import com.github.libretube.util.PlayingQueue
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -65,6 +64,13 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment() {
field = value field = value
} }
private var hideWatched =
PreferenceHelper.getBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, false)
set(value) {
PreferenceHelper.putBoolean(PreferenceKeys.HIDE_WATCHED_FROM_FEED, value)
field = value
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -173,19 +179,25 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment() {
} }
private fun setupSortAndFilter() { private fun setupSortAndFilter() {
binding.filterSort.setOnClickListener { binding.filterSort.setOnClickListener {
val activityCompat = context as AppCompatActivity val activityCompat = context as AppCompatActivity
val fragManager = activityCompat val fragManager = activityCompat
.supportFragmentManager .supportFragmentManager
.apply { .apply {
setFragmentResultListener(FILTER_SORT_REQUEST_KEY, activityCompat) { _, resultBundle -> setFragmentResultListener(FILTER_SORT_REQUEST_KEY, activityCompat) { _, resultBundle ->
selectedSortOrder = resultBundle.getInt(SELECTED_SORT_OPTION_KEY) selectedSortOrder = resultBundle.getInt(IntentData.sortOptions)
hideWatched = resultBundle.getBoolean(IntentData.hideWatched)
showFeed() showFeed()
} }
} }
FilterSortBottomSheet() FilterSortBottomSheet()
.apply { arguments = bundleOf(IntentData.sortOptions to fetchSortOptions()) } .apply {
arguments = bundleOf(
IntentData.sortOptions to fetchSortOptions(),
IntentData.hideWatched to hideWatched
)
}
.show(fragManager) .show(fragManager)
} }
} }
@ -215,7 +227,11 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment() {
PlayingQueue.clear() PlayingQueue.clear()
PlayingQueue.add(*streams.toTypedArray()) PlayingQueue.add(*streams.toTypedArray())
NavigationHelper.navigateVideo(requireContext(), videoUrlOrId = streams.first().url, keepQueue = true) NavigationHelper.navigateVideo(
requireContext(),
videoUrlOrId = streams.first().url,
keepQueue = true
)
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@ -266,23 +282,16 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment() {
val isVideo = !it.isShort && !it.isLive val isVideo = !it.isShort && !it.isLive
return@filter when { return@filter when {
!ContentFilter.SHORTS.isEnabled() && it.isShort -> false !ContentFilter.SHORTS.isEnabled() && it.isShort -> false
!ContentFilter.VIDEOS.isEnabled() && isVideo -> false !ContentFilter.VIDEOS.isEnabled() && isVideo -> false
!ContentFilter.LIVESTREAMS.isEnabled() && it.isLive -> false !ContentFilter.LIVESTREAMS.isEnabled() && it.isLive -> false
else -> true else -> true
} }
} }
if (!PreferenceHelper.getBoolean( return if (hideWatched) runBlocking {
PreferenceKeys.HIDE_WATCHED_FROM_FEED, DatabaseHelper.filterUnwatched(streamItems)
false } else streamItems
)
) {
return streamItems
}
return runBlocking { DatabaseHelper.filterUnwatched(streamItems) }
} }
private fun List<StreamItem>.sortedBySelectedOrder() = when (selectedSortOrder) { private fun List<StreamItem>.sortedBySelectedOrder() = when (selectedSortOrder) {

View File

@ -1,5 +1,6 @@
package com.github.libretube.ui.sheets package com.github.libretube.ui.sheets
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -19,10 +20,17 @@ class FilterSortBottomSheet: ExpandedBottomSheet() {
private lateinit var sortOptions: Array<SelectableOption> private lateinit var sortOptions: Array<SelectableOption>
private var selectedIndex: Int = 0 private var selectedIndex = 0
private var hideWatched = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
sortOptions = requireArguments().getParcelableArray(IntentData.sortOptions) as Array<SelectableOption> sortOptions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requireArguments().getParcelableArray(IntentData.sortOptions, SelectableOption::class.java)!!
} else {
@Suppress("DEPRECATION")
requireArguments().getParcelableArray(IntentData.sortOptions) as Array<SelectableOption>
}
hideWatched = requireArguments().getBoolean(IntentData.hideWatched)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
} }
@ -38,6 +46,7 @@ class FilterSortBottomSheet: ExpandedBottomSheet() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
addSortOptions() addSortOptions()
observeSortChanges() observeSortChanges()
observeHideWatchedChanges()
setInitialFiltersState() setInitialFiltersState()
observeFiltersChanges() observeFiltersChanges()
} }
@ -71,10 +80,18 @@ class FilterSortBottomSheet: ExpandedBottomSheet() {
} }
} }
private fun observeHideWatchedChanges() {
binding.hideWatchedCheckbox.setOnCheckedChangeListener { _, checked ->
hideWatched = checked
notifyChange()
}
}
private fun setInitialFiltersState() { private fun setInitialFiltersState() {
binding.filterVideos.isChecked = ContentFilter.VIDEOS.isEnabled() binding.filterVideos.isChecked = ContentFilter.VIDEOS.isEnabled()
binding.filterShorts.isChecked = ContentFilter.SHORTS.isEnabled() binding.filterShorts.isChecked = ContentFilter.SHORTS.isEnabled()
binding.filterLivestreams.isChecked = ContentFilter.LIVESTREAMS.isEnabled() binding.filterLivestreams.isChecked = ContentFilter.LIVESTREAMS.isEnabled()
binding.hideWatchedCheckbox.isChecked = hideWatched
} }
private fun observeFiltersChanges() { private fun observeFiltersChanges() {
@ -89,7 +106,10 @@ class FilterSortBottomSheet: ExpandedBottomSheet() {
private fun notifyChange() { private fun notifyChange() {
setFragmentResult( setFragmentResult(
requestKey = FILTER_SORT_REQUEST_KEY, requestKey = FILTER_SORT_REQUEST_KEY,
result = bundleOf(SELECTED_SORT_OPTION_KEY to selectedIndex) result = bundleOf(
IntentData.sortOptions to selectedIndex,
IntentData.hideWatched to hideWatched
)
) )
} }
@ -100,7 +120,5 @@ class FilterSortBottomSheet: ExpandedBottomSheet() {
companion object { companion object {
const val FILTER_SORT_REQUEST_KEY = "filter_sort_request_key" const val FILTER_SORT_REQUEST_KEY = "filter_sort_request_key"
const val SELECTED_SORT_OPTION_KEY = "selected_sort_option_key"
} }
} }

View File

@ -89,6 +89,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="16dp"/> android:paddingHorizontal="16dp"/>
<CheckBox
android:id="@+id/hide_watched_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hide_watched_from_feed"
android:layout_marginStart="16dp"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -375,7 +375,7 @@
<string name="nothing_selected">Nothing selected!</string> <string name="nothing_selected">Nothing selected!</string>
<string name="color_violet">Versatile Violet</string> <string name="color_violet">Versatile Violet</string>
<string name="failed_fetching_instances">Could not fetch available instances.</string> <string name="failed_fetching_instances">Could not fetch available instances.</string>
<string name="hide_watched_from_feed">Hide watched videos from feed</string> <string name="hide_watched_from_feed">Hide already watched videos</string>
<string name="hide_watched_from_feed_summary">Don\'t show videos being watched more than 90% in the subscriptions tab</string> <string name="hide_watched_from_feed_summary">Don\'t show videos being watched more than 90% in the subscriptions tab</string>
<string name="playlistUrl">Playlist URL</string> <string name="playlistUrl">Playlist URL</string>
<string name="pause_on_quit">Pause on quit</string> <string name="pause_on_quit">Pause on quit</string>

View File

@ -56,12 +56,6 @@
app:key="confirm_unsubscribing" app:key="confirm_unsubscribing"
app:title="@string/confirm_unsubscribing" /> app:title="@string/confirm_unsubscribing" />
<SwitchPreferenceCompat
android:icon="@drawable/ic_invisible"
android:summary="@string/hide_watched_from_feed_summary"
android:title="@string/hide_watched_from_feed"
app:key="hide_watched_from_feed" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/misc"> <PreferenceCategory app:title="@string/misc">