make watched filter nullable dropdown

This commit is contained in:
Simon 2025-08-11 19:55:27 +07:00
parent 59331b2b40
commit d8e5ee7e04
No known key found for this signature in database
GPG Key ID: 2C15AA5E89985DD4
10 changed files with 42 additions and 12 deletions

View File

@ -38,7 +38,7 @@ class UserMeConfigSerializer(serializers.Serializer):
view_style_downloads = serializers.ChoiceField(choices=["grid", "list"])
view_style_playlist = serializers.ChoiceField(choices=["grid", "list"])
grid_items = serializers.IntegerField(max_value=7, min_value=3)
hide_watched = serializers.BooleanField()
hide_watched = serializers.BooleanField(allow_null=True)
file_size_unit = serializers.ChoiceField(choices=["binary", "metric"])
show_ignored_only = serializers.BooleanField()
show_subed_only = serializers.BooleanField()

View File

@ -21,7 +21,7 @@ class UserConfigType(TypedDict, total=False):
view_style_downloads: str
view_style_playlist: str
grid_items: int
hide_watched: bool
hide_watched: bool | None
file_size_unit: str
show_ignored_only: bool
show_subed_only: bool

View File

@ -112,7 +112,7 @@ class VideoListQuerySerializer(serializers.Serializer):
playlist = serializers.CharField(required=False)
channel = serializers.CharField(required=False)
watch = serializers.ChoiceField(
choices=WatchedEnum.values(), required=False
choices=WatchedEnum.values(), required=False, allow_null=True
)
sort = serializers.ChoiceField(choices=SortEnum.names(), required=False)
order = serializers.ChoiceField(choices=OrderEnum.values(), required=False)

View File

@ -35,7 +35,7 @@ class QueryBuilder:
must_list.append({"match": {"playlist.keyword": playlist}})
watch = self.request_params.get("watch")
if watch:
if watch is not None:
watch_must_list = self.parse_watch(watch)
must_list.append(watch_must_list)

View File

@ -32,7 +32,7 @@ export type UserConfigType = {
view_style_downloads: ViewStylesType;
view_style_playlist: ViewStylesType;
grid_items: number;
hide_watched: boolean;
hide_watched: boolean | null;
file_size_unit: 'binary' | 'metric';
show_ignored_only: boolean;
show_subed_only: boolean;

View File

@ -36,7 +36,7 @@ export const SortOrderEnum = {
export type VideoTypes = 'videos' | 'streams' | 'shorts';
export type WatchTypes = 'watched' | 'unwatched' | 'continue';
export type WatchTypes = 'watched' | 'unwatched' | 'continue' | null;
export const WatchTypesEnum = {
Watched: 'watched',
Unwatched: 'unwatched',

View File

@ -29,6 +29,8 @@ const Filterbar = ({ hideToggleText, viewStyle, showSort = true }: FilterbarProp
const currentViewStyle = userConfig[viewStyle];
const isGridView = currentViewStyle === ViewStylesEnum.Grid;
console.log(hideToggleText);
useEffect(() => {
if (!showSort) {
return;
@ -52,7 +54,21 @@ const Filterbar = ({ hideToggleText, viewStyle, showSort = true }: FilterbarProp
return (
<div className="view-controls three">
<div className="toggle">
<div>
<select
value={userConfig.hide_watched === null ? '' : userConfig.hide_watched.toString()}
onChange={event => {
handleUserConfigUpdate({
hide_watched: event.target.value === '' ? null : event.target.value === 'true',
});
}}
>
<option value="">All</option>
<option value="true">Watched only</option>
<option value="false">Unwatched only</option>
</select>
</div>
{/* <div className="toggle">
<span>{hideToggleText}</span>
<div className="toggleBox">
<input
@ -74,7 +90,7 @@ const Filterbar = ({ hideToggleText, viewStyle, showSort = true }: FilterbarProp
</label>
)}
</div>
</div>
</div> */}
{showHidden && (
<div className="sort">

View File

@ -73,7 +73,12 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
const videos = await loadVideoListByFilter({
channel: channelId,
page: currentPage,
watch: userConfig.hide_watched ? (WatchTypesEnum.Unwatched as WatchTypes) : undefined,
watch:
userConfig.hide_watched === null
? null
: ((userConfig.hide_watched
? WatchTypesEnum.Watched
: WatchTypesEnum.Unwatched) as WatchTypes),
sort: userConfig.sort_by,
order: userConfig.sort_order,
type: videoType,

View File

@ -135,7 +135,12 @@ const Home = () => {
(async () => {
const videos = await loadVideoListByFilter({
page: currentPage,
watch: userConfig.hide_watched ? (WatchTypesEnum.Unwatched as WatchTypes) : undefined,
watch:
userConfig.hide_watched === null
? null
: ((userConfig.hide_watched
? WatchTypesEnum.Watched
: WatchTypesEnum.Unwatched) as WatchTypes),
sort: userConfig.sort_by,
order: userConfig.sort_order,
});

View File

@ -72,7 +72,6 @@ const Playlist = () => {
const viewStyle = userConfig.view_style_home; // its a list of videos, so view_style_home
const gridItems = userConfig.grid_items;
const hideWatched = userConfig.hide_watched;
const isGridView = viewStyle === ViewStylesEnum.Grid;
const gridView = isGridView ? `boxed-${gridItems}` : '';
const gridViewGrid = isGridView ? `grid-${gridItems}` : '';
@ -83,7 +82,12 @@ const Playlist = () => {
const video = await loadVideoListByFilter({
playlist: playlistId,
page: currentPage,
watch: hideWatched ? (WatchTypesEnum.Unwatched as WatchTypes) : undefined,
watch:
userConfig.hide_watched === null
? null
: ((userConfig.hide_watched
? WatchTypesEnum.Watched
: WatchTypesEnum.Unwatched) as WatchTypes),
});
setPlaylistResponse(playlist);