1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

use filtermenu

This commit is contained in:
grafixeyehero 2022-10-03 02:33:43 +03:00
parent 0acac1b52d
commit 0dc9ad8904
7 changed files with 215 additions and 51 deletions

View file

@ -1,38 +1,53 @@
import React, { FC, useCallback, useEffect, useRef } from 'react'; import React, { FC, useCallback, useEffect, useRef } from 'react';
import { Events } from 'jellyfin-apiclient';
import IconButtonElement from '../../elements/IconButtonElement'; import IconButtonElement from '../../elements/IconButtonElement';
import { QueryI } from './interface'; import { FiltersI } from './interface';
interface FilterI { interface FilterI {
query: QueryI; topParentId?: string | null;
getFilterMode: () => string | null; getItemTypes: () => string[];
getFilters: () => FiltersI;
getSettingsKey: () => string;
getFilterMenuOptions: () => Record<string, never>;
getVisibleFilters: () => string[];
reloadItems: () => void; reloadItems: () => void;
} }
const Filter: FC<FilterI> = ({ query, getFilterMode, reloadItems }) => { const Filter: FC<FilterI> = ({
topParentId,
getItemTypes,
getSettingsKey,
getFilters,
getVisibleFilters,
getFilterMenuOptions,
reloadItems
}) => {
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const showFilterMenu = useCallback(() => { const showFilterMenu = useCallback(() => {
import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { import('../../components/filtermenu/filtermenu').then(({default: FilterMenu}) => {
const filterDialog = new filterDialogFactory({ const filterMenu = new FilterMenu();
query: query, filterMenu.show({
mode: getFilterMode(), settingsKey: getSettingsKey(),
serverId: window.ApiClient.serverId() settings: getFilters(),
}); visibleSettings: getVisibleFilters(),
Events.on(filterDialog, 'filterchange', () => { parentId: topParentId,
query.StartIndex = 0; itemTypes: getItemTypes(),
serverId: window.ApiClient.serverId(),
filterMenuOptions: getFilterMenuOptions()
}).then(() => {
reloadItems(); reloadItems();
}); });
filterDialog.show();
}); });
}, [getFilterMode, query, reloadItems]); }, [getSettingsKey, getFilters, getVisibleFilters, topParentId, getItemTypes, getFilterMenuOptions, reloadItems]);
useEffect(() => { useEffect(() => {
const btnFilter = element.current?.querySelector('.btnFilter'); const btnFilter = element.current?.querySelector('.btnFilter');
if (btnFilter) { btnFilter?.addEventListener('click', showFilterMenu);
btnFilter.addEventListener('click', showFilterMenu);
} return () => {
btnFilter?.removeEventListener('click', showFilterMenu);
};
}, [showFilterMenu]); }, [showFilterMenu]);
return ( return (

View file

@ -21,8 +21,7 @@ interface ViewItemsContainerI {
isBtnNewCollectionEnabled?: boolean; isBtnNewCollectionEnabled?: boolean;
isAlphaPickerEnabled?: boolean; isAlphaPickerEnabled?: boolean;
getBasekey: () => string; getBasekey: () => string;
getFilterMode: () => string; getItemTypes: () => string[];
getItemTypes: () => string;
getNoItemsMessage: () => string; getNoItemsMessage: () => string;
} }
@ -33,7 +32,6 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
isBtnNewCollectionEnabled = false, isBtnNewCollectionEnabled = false,
isAlphaPickerEnabled = true, isAlphaPickerEnabled = true,
getBasekey, getBasekey,
getFilterMode,
getItemTypes, getItemTypes,
getNoItemsMessage getNoItemsMessage
}) => { }) => {
@ -62,11 +60,52 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
}; };
}, [getDefaultSortBy, getSettingsKey]); }, [getDefaultSortBy, getSettingsKey]);
const getFilters = useCallback(() => {
const basekey = getSettingsKey();
return {
IsPlayed: userSettings.getFilter(basekey + '-filter-IsPlayed') === 'true',
IsUnplayed: userSettings.getFilter(basekey + '-filter-IsUnplayed') === 'true',
IsFavorite: userSettings.getFilter(basekey + '-filter-IsFavorite') === 'true',
IsResumable: userSettings.getFilter(basekey + '-filter-IsResumable') === 'true',
Is4K: userSettings.getFilter(basekey + '-filter-Is4K') === 'true',
IsHD: userSettings.getFilter(basekey + '-filter-IsHD') === 'true',
IsSD: userSettings.getFilter(basekey + '-filter-IsSD') === 'true',
Is3D: userSettings.getFilter(basekey + '-filter-Is3D') === 'true',
VideoTypes: userSettings.getFilter(basekey + '-filter-VideoTypes'),
SeriesStatus: userSettings.getFilter(basekey + '-filter-SeriesStatus'),
HasSubtitles: userSettings.getFilter(basekey + '-filter-HasSubtitles'),
HasTrailer: userSettings.getFilter(basekey + '-filter-HasTrailer'),
HasSpecialFeature: userSettings.getFilter(basekey + '-filter-HasSpecialFeature'),
HasThemeSong: userSettings.getFilter(basekey + '-filter-HasThemeSong'),
HasThemeVideo: userSettings.getFilter(basekey + '-filter-HasThemeVideo'),
GenreIds: userSettings.getFilter(basekey + '-filter-GenreIds')
};
}, [getSettingsKey]);
const getFilterMenuOptions = useCallback(() => {
return {};
}, []);
const getVisibleFilters = useCallback(() => {
return [
'IsUnplayed',
'IsPlayed',
'IsFavorite',
'IsResumable',
'VideoType',
'HasSubtitles',
'HasTrailer',
'HasSpecialFeature',
'HasThemeSong',
'HasThemeVideo'
];
}, []);
const getQuery = useCallback(() => { const getQuery = useCallback(() => {
const query: QueryI = { const query: QueryI = {
SortBy: getSortValues().sortBy, SortBy: getSortValues().sortBy,
SortOrder: getSortValues().sortOrder, SortOrder: getSortValues().sortOrder,
IncludeItemTypes: getItemTypes(), IncludeItemTypes: getItemTypes().join(','),
Recursive: true, Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo', Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
ImageTypeLimit: 1, ImageTypeLimit: 1,
@ -84,6 +123,97 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
return query; return query;
}, [getSortValues, getItemTypes, topParentId, getBasekey, getSettingsKey]); }, [getSortValues, getItemTypes, topParentId, getBasekey, getSettingsKey]);
const getQueryWithFilters = useCallback(() => {
const query = getQuery();
const queryFilters = [];
let hasFilters;
const filters = getFilters();
if (filters.IsPlayed) {
queryFilters.push('IsPlayed');
hasFilters = true;
}
if (filters.IsUnplayed) {
queryFilters.push('IsUnplayed');
hasFilters = true;
}
if (filters.IsFavorite) {
queryFilters.push('IsFavorite');
hasFilters = true;
}
if (filters.IsResumable) {
queryFilters.push('IsResumable');
hasFilters = true;
}
if (filters.VideoTypes) {
hasFilters = true;
query.VideoTypes = filters.VideoTypes;
}
if (filters.GenreIds) {
hasFilters = true;
query.GenreIds = filters.GenreIds;
}
if (filters.Is4K) {
query.Is4K = true;
hasFilters = true;
}
if (filters.IsHD) {
query.IsHD = true;
hasFilters = true;
}
if (filters.IsSD) {
query.IsHD = false;
hasFilters = true;
}
if (filters.Is3D) {
query.Is3D = true;
hasFilters = true;
}
if (filters.HasSubtitles) {
query.HasSubtitles = true;
hasFilters = true;
}
if (filters.HasTrailer) {
query.HasTrailer = true;
hasFilters = true;
}
if (filters.HasSpecialFeature) {
query.HasSpecialFeature = true;
hasFilters = true;
}
if (filters.HasThemeSong) {
query.HasThemeSong = true;
hasFilters = true;
}
if (filters.HasThemeVideo) {
query.HasThemeVideo = true;
hasFilters = true;
}
query.Filters = queryFilters.length ? queryFilters.join(',') : null;
return {
query: query,
hasFilters: hasFilters
};
}, [getQuery, getFilters]);
const getSortMenuOptions = useCallback(() => { const getSortMenuOptions = useCallback(() => {
return [{ return [{
name: globalize.translate('Name'), name: globalize.translate('Name'),
@ -123,7 +253,7 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
}, [getViewSettings]); }, [getViewSettings]);
const getContext = useCallback(() => { const getContext = useCallback(() => {
const itemType = getItemTypes(); const itemType = getItemTypes().join(',');
if (itemType === 'Movie' || itemType === 'BoxSet') { if (itemType === 'Movie' || itemType === 'BoxSet') {
return 'movies'; return 'movies';
} }
@ -139,8 +269,8 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
return; return;
} }
loading.show(); loading.show();
const query = getQuery(); const querywithfilters = getQueryWithFilters().query;
window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), query).then((result) => { window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), querywithfilters).then((result) => {
setItemsResult(result); setItemsResult(result);
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -150,7 +280,7 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
autoFocuser.autoFocus(page); autoFocuser.autoFocus(page);
}); });
}); });
}, [getQuery]); }, [getQueryWithFilters]);
useEffect(() => { useEffect(() => {
reloadItems(); reloadItems();
@ -171,7 +301,15 @@ const ViewItemsContainer: FC<ViewItemsContainerI> = ({
reloadItems={reloadItems} reloadItems={reloadItems}
/> />
{isBtnFilterEnabled && <Filter query={getQuery()} getFilterMode={getFilterMode} reloadItems={reloadItems} />} {isBtnFilterEnabled && <Filter
topParentId={topParentId}
getFilters={getFilters}
getSettingsKey={getSettingsKey}
getItemTypes={getItemTypes}
getVisibleFilters={getVisibleFilters}
getFilterMenuOptions={getFilterMenuOptions}
reloadItems={reloadItems}
/>}
{isBtnNewCollectionEnabled && <NewCollection />} {isBtnNewCollectionEnabled && <NewCollection />}

View file

@ -12,8 +12,39 @@ export interface QueryI {
IsFavorite?: boolean; IsFavorite?: boolean;
IsMissing?: boolean; IsMissing?: boolean;
Limit:number; Limit:number;
NameStartsWithOrGreater?: string;
NameLessThan?: string; NameLessThan?: string;
NameStartsWith?: string; NameStartsWith?: string;
VideoTypes?: string;
GenreIds?: string;
Is4K?: boolean;
IsHD?: boolean;
Is3D?: boolean;
HasSubtitles?: boolean;
HasTrailer?: boolean;
HasSpecialFeature?: boolean;
HasThemeSong?: boolean;
HasThemeVideo?: boolean;
Filters?: string | null;
}
export interface FiltersI {
IsPlayed: boolean;
IsUnplayed: boolean;
IsFavorite: boolean;
IsResumable: boolean;
Is4K: boolean;
IsHD: boolean;
IsSD: boolean;
Is3D: boolean;
VideoTypes: string;
SeriesStatus: string;
HasSubtitles: string;
HasTrailer: string;
HasSpecialFeature: string;
HasThemeSong: string;
HasThemeVideo: string;
GenreIds: string;
} }
export interface CardOptionsI { export interface CardOptionsI {

View file

@ -11,12 +11,8 @@ const CollectionsView: FC<CollectionsViewI> = ({ topParentId }) => {
return 'collections'; return 'collections';
}, []); }, []);
const getFilterMode = useCallback(() => {
return 'movies';
}, []);
const getItemTypes = useCallback(() => { const getItemTypes = useCallback(() => {
return 'BoxSet'; return ['BoxSet'];
}, []); }, []);
const getNoItemsMessage = useCallback(() => { const getNoItemsMessage = useCallback(() => {
@ -30,7 +26,6 @@ const CollectionsView: FC<CollectionsViewI> = ({ topParentId }) => {
isBtnNewCollectionEnabled={true} isBtnNewCollectionEnabled={true}
isAlphaPickerEnabled={false} isAlphaPickerEnabled={false}
getBasekey={getBasekey} getBasekey={getBasekey}
getFilterMode={getFilterMode}
getItemTypes={getItemTypes} getItemTypes={getItemTypes}
getNoItemsMessage={getNoItemsMessage} getNoItemsMessage={getNoItemsMessage}
/> />

View file

@ -11,12 +11,8 @@ const FavoritesView: FC<FavoritesViewI> = ({ topParentId }) => {
return 'favorites'; return 'favorites';
}, []); }, []);
const getFilterMode = useCallback(() => {
return 'movies';
}, []);
const getItemTypes = useCallback(() => { const getItemTypes = useCallback(() => {
return 'Movie'; return ['Movie'];
}, []); }, []);
const getNoItemsMessage = useCallback(() => { const getNoItemsMessage = useCallback(() => {
@ -27,7 +23,6 @@ const FavoritesView: FC<FavoritesViewI> = ({ topParentId }) => {
<ViewItemsContainer <ViewItemsContainer
topParentId={topParentId} topParentId={topParentId}
getBasekey={getBasekey} getBasekey={getBasekey}
getFilterMode={getFilterMode}
getItemTypes={getItemTypes} getItemTypes={getItemTypes}
getNoItemsMessage={getNoItemsMessage} getNoItemsMessage={getNoItemsMessage}
/> />

View file

@ -11,12 +11,8 @@ const MoviesView: FC<MoviesViewI> = ({ topParentId }) => {
return 'movies'; return 'movies';
}, []); }, []);
const getFilterMode = useCallback(() => {
return 'movies';
}, []);
const getItemTypes = useCallback(() => { const getItemTypes = useCallback(() => {
return 'Movie'; return ['Movie'];
}, []); }, []);
const getNoItemsMessage = useCallback(() => { const getNoItemsMessage = useCallback(() => {
@ -28,7 +24,6 @@ const MoviesView: FC<MoviesViewI> = ({ topParentId }) => {
topParentId={topParentId} topParentId={topParentId}
isBtnShuffleEnabled={true} isBtnShuffleEnabled={true}
getBasekey={getBasekey} getBasekey={getBasekey}
getFilterMode={getFilterMode}
getItemTypes={getItemTypes} getItemTypes={getItemTypes}
getNoItemsMessage={getNoItemsMessage} getNoItemsMessage={getNoItemsMessage}
/> />

View file

@ -12,12 +12,8 @@ const TrailersView: FC<TrailersViewI> = ({ topParentId }) => {
return 'trailers'; return 'trailers';
}, []); }, []);
const getFilterMode = useCallback(() => {
return 'movies';
}, []);
const getItemTypes = useCallback(() => { const getItemTypes = useCallback(() => {
return 'Trailer'; return ['Trailer'];
}, []); }, []);
const getNoItemsMessage = useCallback(() => { const getNoItemsMessage = useCallback(() => {
@ -28,7 +24,6 @@ const TrailersView: FC<TrailersViewI> = ({ topParentId }) => {
<ViewItemsContainer <ViewItemsContainer
topParentId={topParentId} topParentId={topParentId}
getBasekey={getBasekey} getBasekey={getBasekey}
getFilterMode={getFilterMode}
getItemTypes={getItemTypes} getItemTypes={getItemTypes}
getNoItemsMessage={getNoItemsMessage} getNoItemsMessage={getNoItemsMessage}
/> />