mirror of
https://git.vectorsigma.ru/public/tubearchivist.git
synced 2026-08-04 19:09:29 +00:00
watched filter split by channel and playlist
This commit is contained in:
@@ -42,6 +42,8 @@ class UserMeConfigSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
grid_items = serializers.IntegerField(max_value=7, min_value=3)
|
grid_items = serializers.IntegerField(max_value=7, min_value=3)
|
||||||
hide_watched = serializers.BooleanField(allow_null=True)
|
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"])
|
file_size_unit = serializers.ChoiceField(choices=["binary", "metric"])
|
||||||
show_ignored_only = serializers.BooleanField()
|
show_ignored_only = serializers.BooleanField()
|
||||||
show_subed_only = serializers.BooleanField(allow_null=True)
|
show_subed_only = serializers.BooleanField(allow_null=True)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ class UserConfigType(TypedDict, total=False):
|
|||||||
vid_type_filter: str | None
|
vid_type_filter: str | None
|
||||||
grid_items: int
|
grid_items: int
|
||||||
hide_watched: bool | None
|
hide_watched: bool | None
|
||||||
|
hide_watched_channel: bool | None
|
||||||
|
hide_watched_playlist: bool | None
|
||||||
file_size_unit: str
|
file_size_unit: str
|
||||||
show_ignored_only: bool
|
show_ignored_only: bool
|
||||||
show_subed_only: bool | None
|
show_subed_only: bool | None
|
||||||
@@ -48,6 +50,8 @@ class UserConfig:
|
|||||||
vid_type_filter=None,
|
vid_type_filter=None,
|
||||||
grid_items=3,
|
grid_items=3,
|
||||||
hide_watched=False,
|
hide_watched=False,
|
||||||
|
hide_watched_channel=None,
|
||||||
|
hide_watched_playlist=None,
|
||||||
file_size_unit="binary",
|
file_size_unit="binary",
|
||||||
show_ignored_only=False,
|
show_ignored_only=False,
|
||||||
show_subed_only=None,
|
show_subed_only=None,
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export type UserConfigType = {
|
|||||||
vid_type_filter: VideoTypes | null;
|
vid_type_filter: VideoTypes | null;
|
||||||
grid_items: number;
|
grid_items: number;
|
||||||
hide_watched: boolean | null;
|
hide_watched: boolean | null;
|
||||||
|
hide_watched_channel: boolean | null;
|
||||||
|
hide_watched_playlist: boolean | null;
|
||||||
file_size_unit: 'binary' | 'metric';
|
file_size_unit: 'binary' | 'metric';
|
||||||
show_ignored_only: boolean;
|
show_ignored_only: boolean;
|
||||||
show_subed_only: boolean | null;
|
show_subed_only: boolean | null;
|
||||||
|
|||||||
@@ -21,14 +21,21 @@ import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
|||||||
import { useVideoSelectionStore } from '../stores/VideoSelectionStore';
|
import { useVideoSelectionStore } from '../stores/VideoSelectionStore';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import updateDownloadQueue from '../api/actions/updateDownloadQueue';
|
import updateDownloadQueue from '../api/actions/updateDownloadQueue';
|
||||||
|
import { HideWatchedType } from '../configuration/constants/HideWatched';
|
||||||
|
|
||||||
type FilterbarProps = {
|
type FilterbarProps = {
|
||||||
viewStyle: ViewStyleNamesType;
|
viewStyle: ViewStyleNamesType;
|
||||||
|
hideWatched: HideWatchedType;
|
||||||
showSort?: boolean;
|
showSort?: boolean;
|
||||||
showTypeFilter?: 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 { userConfig, setUserConfig } = useUserConfigStore();
|
||||||
const {
|
const {
|
||||||
selectedVideoIds,
|
selectedVideoIds,
|
||||||
@@ -44,6 +51,7 @@ const Filterbar = ({ viewStyle, showSort = true, showTypeFilter = false }: Filte
|
|||||||
useFilterBarTempConf();
|
useFilterBarTempConf();
|
||||||
|
|
||||||
const currentViewStyle = userConfig[viewStyle];
|
const currentViewStyle = userConfig[viewStyle];
|
||||||
|
const currentHideWatched = userConfig[hideWatched];
|
||||||
const isGridView = currentViewStyle === ViewStylesEnum.Grid;
|
const isGridView = currentViewStyle === ViewStylesEnum.Grid;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -114,10 +122,10 @@ const Filterbar = ({ viewStyle, showSort = true, showTypeFilter = false }: Filte
|
|||||||
<div>
|
<div>
|
||||||
<span>Filter:</span>
|
<span>Filter:</span>
|
||||||
<select
|
<select
|
||||||
value={userConfig.hide_watched === null ? '' : userConfig.hide_watched.toString()}
|
value={currentHideWatched === null ? '' : currentHideWatched.toString()}
|
||||||
onChange={event => {
|
onChange={event => {
|
||||||
handleUserConfigUpdate({
|
handleUserConfigUpdate({
|
||||||
hide_watched: event.target.value === '' ? null : event.target.value === 'true',
|
[hideWatched]: event.target.value === '' ? null : event.target.value === 'true',
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
7
frontend/src/configuration/constants/HideWatched.ts
Normal file
7
frontend/src/configuration/constants/HideWatched.ts
Normal 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',
|
||||||
|
};
|
||||||
@@ -28,6 +28,7 @@ import { useUserConfigStore } from '../stores/UserConfigStore';
|
|||||||
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
import { FileSizeUnits } from '../api/actions/updateUserConfig';
|
||||||
import { ApiResponseType } from '../functions/APIClient';
|
import { ApiResponseType } from '../functions/APIClient';
|
||||||
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
||||||
|
import { HideWatchedName, HideWatchedType } from '../configuration/constants/HideWatched';
|
||||||
|
|
||||||
type ChannelParams = {
|
type ChannelParams = {
|
||||||
channelId: string;
|
channelId: string;
|
||||||
@@ -76,9 +77,9 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
|
|||||||
channel: channelId,
|
channel: channelId,
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
watch:
|
watch:
|
||||||
userConfig.hide_watched === null
|
userConfig.hide_watched_channel === null
|
||||||
? null
|
? null
|
||||||
: ((userConfig.hide_watched
|
: ((userConfig.hide_watched_channel
|
||||||
? WatchTypesEnum.Watched
|
? WatchTypesEnum.Watched
|
||||||
: WatchTypesEnum.Unwatched) as WatchTypes),
|
: WatchTypesEnum.Unwatched) as WatchTypes),
|
||||||
sort: userConfig.sort_by,
|
sort: userConfig.sort_by,
|
||||||
@@ -97,7 +98,7 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
|
|||||||
refresh,
|
refresh,
|
||||||
userConfig.sort_by,
|
userConfig.sort_by,
|
||||||
userConfig.sort_order,
|
userConfig.sort_order,
|
||||||
userConfig.hide_watched,
|
userConfig.hide_watched_channel,
|
||||||
filterHeight,
|
filterHeight,
|
||||||
currentPage,
|
currentPage,
|
||||||
channelId,
|
channelId,
|
||||||
@@ -167,7 +168,10 @@ const ChannelVideo = ({ videoType }: ChannelVideoProps) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`boxed-content ${gridView}`}>
|
<div className={`boxed-content ${gridView}`}>
|
||||||
<Filterbar viewStyle={ViewStyleNames.Home as ViewStyleNamesType} />
|
<Filterbar
|
||||||
|
viewStyle={ViewStyleNames.Home as ViewStyleNamesType}
|
||||||
|
hideWatched={HideWatchedName.Channel as HideWatchedType}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<EmbeddableVideoPlayer videoId={videoId} />
|
<EmbeddableVideoPlayer videoId={videoId} />
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { SponsorBlockType } from './Video';
|
|||||||
import { useUserConfigStore } from '../stores/UserConfigStore';
|
import { useUserConfigStore } from '../stores/UserConfigStore';
|
||||||
import { ApiResponseType } from '../functions/APIClient';
|
import { ApiResponseType } from '../functions/APIClient';
|
||||||
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
||||||
|
import { HideWatchedName, HideWatchedType } from '../configuration/constants/HideWatched';
|
||||||
|
|
||||||
export type PlayerType = {
|
export type PlayerType = {
|
||||||
watched: boolean;
|
watched: boolean;
|
||||||
@@ -202,7 +203,11 @@ const Home = () => {
|
|||||||
<h1>Recent Videos</h1>
|
<h1>Recent Videos</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Filterbar viewStyle={ViewStyleNames.Home as ViewStyleNamesType} showTypeFilter={true} />
|
<Filterbar
|
||||||
|
viewStyle={ViewStyleNames.Home as ViewStyleNamesType}
|
||||||
|
hideWatched={HideWatchedName.Home as HideWatchedType}
|
||||||
|
showTypeFilter={true}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`boxed-content ${gridView}`}>
|
<div className={`boxed-content ${gridView}`}>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import { ApiResponseType } from '../functions/APIClient';
|
|||||||
import NotFound from './NotFound';
|
import NotFound from './NotFound';
|
||||||
import updatePlaylistSortOrder from '../api/actions/updatePlaylistSortOrder';
|
import updatePlaylistSortOrder from '../api/actions/updatePlaylistSortOrder';
|
||||||
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
import { useFilterBarTempConf } from '../stores/FilterbarTempConf';
|
||||||
|
import { HideWatchedType, HideWatchedName } from '../configuration/constants/HideWatched';
|
||||||
|
|
||||||
export type VideoResponseType = {
|
export type VideoResponseType = {
|
||||||
data?: VideoType[];
|
data?: VideoType[];
|
||||||
@@ -86,9 +87,9 @@ const Playlist = () => {
|
|||||||
playlist: playlistId,
|
playlist: playlistId,
|
||||||
page: currentPage,
|
page: currentPage,
|
||||||
watch:
|
watch:
|
||||||
userConfig.hide_watched === null
|
userConfig.hide_watched_playlist === null
|
||||||
? null
|
? null
|
||||||
: ((userConfig.hide_watched
|
: ((userConfig.hide_watched_playlist
|
||||||
? WatchTypesEnum.Watched
|
? WatchTypesEnum.Watched
|
||||||
: WatchTypesEnum.Unwatched) as WatchTypes),
|
: WatchTypesEnum.Unwatched) as WatchTypes),
|
||||||
type: userConfig.vid_type_filter as VideoTypes,
|
type: userConfig.vid_type_filter as VideoTypes,
|
||||||
@@ -110,7 +111,7 @@ const Playlist = () => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [
|
}, [
|
||||||
playlistId,
|
playlistId,
|
||||||
userConfig.hide_watched,
|
userConfig.hide_watched_playlist,
|
||||||
userConfig.vid_type_filter,
|
userConfig.vid_type_filter,
|
||||||
filterHeight,
|
filterHeight,
|
||||||
refresh,
|
refresh,
|
||||||
@@ -351,6 +352,7 @@ const Playlist = () => {
|
|||||||
<div className={`boxed-content ${gridView}`}>
|
<div className={`boxed-content ${gridView}`}>
|
||||||
<Filterbar
|
<Filterbar
|
||||||
viewStyle={ViewStyleNames.Home as ViewStyleNamesType} // its a list of videos, so ViewStyleNames.Home
|
viewStyle={ViewStyleNames.Home as ViewStyleNamesType} // its a list of videos, so ViewStyleNames.Home
|
||||||
|
hideWatched={HideWatchedName.Playlist as HideWatchedType}
|
||||||
showSort={false}
|
showSort={false}
|
||||||
showTypeFilter={true}
|
showTypeFilter={true}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ export const useUserConfigStore = create<UserConfigState>(set => ({
|
|||||||
view_style_playlist: ViewStylesEnum.Grid as ViewStylesType,
|
view_style_playlist: ViewStylesEnum.Grid as ViewStylesType,
|
||||||
vid_type_filter: null,
|
vid_type_filter: null,
|
||||||
grid_items: 3,
|
grid_items: 3,
|
||||||
hide_watched: false,
|
hide_watched: null,
|
||||||
|
hide_watched_channel: null,
|
||||||
|
hide_watched_playlist: null,
|
||||||
file_size_unit: 'binary',
|
file_size_unit: 'binary',
|
||||||
show_ignored_only: false,
|
show_ignored_only: false,
|
||||||
show_subed_only: null,
|
show_subed_only: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user