Separate watched filter, #build

Changed:
- Split watched state filter by home, channel videos and playlist videos
- Bumped yt-dlp
This commit is contained in:
Simon 2025-08-23 12:33:31 +07:00
commit 005d2d1cf5
No known key found for this signature in database
GPG Key ID: 2C15AA5E89985DD4
11 changed files with 50 additions and 14 deletions

View File

@ -223,7 +223,7 @@ CORS_ALLOW_HEADERS = list(default_headers) + [
# TA application settings
TA_UPSTREAM = "https://github.com/tubearchivist/tubearchivist"
TA_VERSION = "v0.5.7"
TA_VERSION = "v0.5.8-unstable"
# API
REST_FRAMEWORK = {

View File

@ -12,4 +12,4 @@ requests==2.32.5
ryd-client==0.0.6
uvicorn==0.35.0
whitenoise==6.9.0
yt-dlp[default]==2025.8.20
yt-dlp[default]==2025.8.22

View File

@ -42,6 +42,8 @@ class UserMeConfigSerializer(serializers.Serializer):
)
grid_items = serializers.IntegerField(max_value=7, min_value=3)
hide_watched = serializers.BooleanField(allow_null=True)
hide_watched_channel = serializers.BooleanField(allow_null=True)
hide_watched_playlist = serializers.BooleanField(allow_null=True)
file_size_unit = serializers.ChoiceField(choices=["binary", "metric"])
show_ignored_only = serializers.BooleanField()
show_subed_only = serializers.BooleanField(allow_null=True)

View File

@ -23,6 +23,8 @@ class UserConfigType(TypedDict, total=False):
vid_type_filter: str | None
grid_items: int
hide_watched: bool | None
hide_watched_channel: bool | None
hide_watched_playlist: bool | None
file_size_unit: str
show_ignored_only: bool
show_subed_only: bool | None
@ -48,6 +50,8 @@ class UserConfig:
vid_type_filter=None,
grid_items=3,
hide_watched=False,
hide_watched_channel=None,
hide_watched_playlist=None,
file_size_unit="binary",
show_ignored_only=False,
show_subed_only=None,

View File

@ -34,6 +34,8 @@ export type UserConfigType = {
vid_type_filter: VideoTypes | null;
grid_items: number;
hide_watched: boolean | null;
hide_watched_channel: boolean | null;
hide_watched_playlist: boolean | null;
file_size_unit: 'binary' | 'metric';
show_ignored_only: boolean;
show_subed_only: boolean | null;

View File

@ -21,14 +21,21 @@ import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
import { useVideoSelectionStore } from '../stores/VideoSelectionStore';
import Button from './Button';
import updateDownloadQueue from '../api/actions/updateDownloadQueue';
import { HideWatchedType } from '../configuration/constants/HideWatched';
type FilterbarProps = {
viewStyle: ViewStyleNamesType;
hideWatched: HideWatchedType;
showSort?: boolean;
showTypeFilter?: boolean;
};
const Filterbar = ({ viewStyle, showSort = true, showTypeFilter = false }: FilterbarProps) => {
const Filterbar = ({
viewStyle,
hideWatched,
showSort = true,
showTypeFilter = false,
}: FilterbarProps) => {
const { userConfig, setUserConfig } = useUserConfigStore();
const {
selectedVideoIds,
@ -44,6 +51,7 @@ const Filterbar = ({ viewStyle, showSort = true, showTypeFilter = false }: Filte
useFilterBarTempConf();
const currentViewStyle = userConfig[viewStyle];
const currentHideWatched = userConfig[hideWatched];
const isGridView = currentViewStyle === ViewStylesEnum.Grid;
useEffect(() => {
@ -114,10 +122,10 @@ const Filterbar = ({ viewStyle, showSort = true, showTypeFilter = false }: Filte
<div>
<span>Filter:</span>
<select
value={userConfig.hide_watched === null ? '' : userConfig.hide_watched.toString()}
value={currentHideWatched === null ? '' : currentHideWatched.toString()}
onChange={event => {
handleUserConfigUpdate({
hide_watched: event.target.value === '' ? null : event.target.value === 'true',
[hideWatched]: event.target.value === '' ? null : event.target.value === 'true',
});
}}
>

View File

@ -0,0 +1,7 @@
export type HideWatchedType = 'hide_watched' | 'hide_watched_channel' | 'hide_watched_playlist';
export const HideWatchedName = {
Home: 'hide_watched',
Channel: 'hide_watched_channel',
Playlist: 'hide_watched_playlist',
};

View File

@ -28,6 +28,7 @@ import { useUserConfigStore } from '../stores/UserConfigStore';
import { FileSizeUnits } from '../api/actions/updateUserConfig';
import { ApiResponseType } from '../functions/APIClient';
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
import { HideWatchedName, HideWatchedType } from '../configuration/constants/HideWatched';
type ChannelParams = {
channelId: string;
@ -76,9 +77,9 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
channel: channelId,
page: currentPage,
watch:
userConfig.hide_watched === null
userConfig.hide_watched_channel === null
? null
: ((userConfig.hide_watched
: ((userConfig.hide_watched_channel
? WatchTypesEnum.Watched
: WatchTypesEnum.Unwatched) as WatchTypes),
sort: userConfig.sort_by,
@ -97,7 +98,7 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
refresh,
userConfig.sort_by,
userConfig.sort_order,
userConfig.hide_watched,
userConfig.hide_watched_channel,
filterHeight,
currentPage,
channelId,
@ -167,7 +168,10 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
</div>
<div className={`boxed-content ${gridView}`}>
<Filterbar viewStyle={ViewStyleNames.Home as ViewStyleNamesType} />
<Filterbar
viewStyle={ViewStyleNames.Home as ViewStyleNamesType}
hideWatched={HideWatchedName.Channel as HideWatchedType}
/>
</div>
<EmbeddableVideoPlayer videoId={videoId} />

View File

@ -23,6 +23,7 @@ import { SponsorBlockType } from './Video';
import { useUserConfigStore } from '../stores/UserConfigStore';
import { ApiResponseType } from '../functions/APIClient';
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
import { HideWatchedName, HideWatchedType } from '../configuration/constants/HideWatched';
export type PlayerType = {
watched: boolean;
@ -202,7 +203,11 @@ const Home = () => {
<h1>Recent Videos</h1>
</div>
<Filterbar viewStyle={ViewStyleNames.Home as ViewStyleNamesType} showTypeFilter={true} />
<Filterbar
viewStyle={ViewStyleNames.Home as ViewStyleNamesType}
hideWatched={HideWatchedName.Home as HideWatchedType}
showTypeFilter={true}
/>
</div>
<div className={`boxed-content ${gridView}`}>

View File

@ -34,6 +34,7 @@ import { ApiResponseType } from '../functions/APIClient';
import NotFound from './NotFound';
import updatePlaylistSortOrder from '../api/actions/updatePlaylistSortOrder';
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
import { HideWatchedType, HideWatchedName } from '../configuration/constants/HideWatched';
export type VideoResponseType = {
data?: VideoType[];
@ -86,9 +87,9 @@ const Playlist = () => {
playlist: playlistId,
page: currentPage,
watch:
userConfig.hide_watched === null
userConfig.hide_watched_playlist === null
? null
: ((userConfig.hide_watched
: ((userConfig.hide_watched_playlist
? WatchTypesEnum.Watched
: WatchTypesEnum.Unwatched) as WatchTypes),
type: userConfig.vid_type_filter as VideoTypes,
@ -110,7 +111,7 @@ const Playlist = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
playlistId,
userConfig.hide_watched,
userConfig.hide_watched_playlist,
userConfig.vid_type_filter,
filterHeight,
refresh,
@ -351,6 +352,7 @@ const Playlist = () => {
<div className={`boxed-content ${gridView}`}>
<Filterbar
viewStyle={ViewStyleNames.Home as ViewStyleNamesType} // its a list of videos, so ViewStyleNames.Home
hideWatched={HideWatchedName.Playlist as HideWatchedType}
showSort={false}
showTypeFilter={true}
/>

View File

@ -20,7 +20,9 @@ export const useUserConfigStore = create<UserConfigState>(set => ({
view_style_playlist: ViewStylesEnum.Grid as ViewStylesType,
vid_type_filter: null,
grid_items: 3,
hide_watched: false,
hide_watched: null,
hide_watched_channel: null,
hide_watched_playlist: null,
file_size_unit: 'binary',
show_ignored_only: false,
show_subed_only: null,