diff --git a/front/packages/ui/src/browse/header.tsx b/front/packages/ui/src/browse/header.tsx index 5deaf780..daf21e3e 100644 --- a/front/packages/ui/src/browse/header.tsx +++ b/front/packages/ui/src/browse/header.tsx @@ -19,7 +19,6 @@ */ import { - Chip, HR, Icon, IconButton, @@ -33,15 +32,13 @@ import ArrowDownward from "@material-symbols/svg-400/rounded/arrow_downward.svg" import ArrowUpward from "@material-symbols/svg-400/rounded/arrow_upward.svg"; import GridView from "@material-symbols/svg-400/rounded/grid_view.svg"; import Sort from "@material-symbols/svg-400/rounded/sort.svg"; -import Style from "@material-symbols/svg-400/rounded/style.svg"; import FilterList from "@material-symbols/svg-400/rounded/filter_list.svg"; import ViewList from "@material-symbols/svg-400/rounded/view_list.svg"; -import {type ComponentType, forwardRef} from "react"; +import {forwardRef} from "react"; import { useTranslation } from "react-i18next"; import { type PressableProps, View } from "react-native"; import { useYoshiki } from "yoshiki/native"; -import {AllMediaTypes, Layout, SearchSort, SortOrd} from "./types"; -import type {SvgProps} from "react-native-svg"; +import {Layout, MediaType, MediaTypeAll, SearchSort, SortOrd} from "./types"; const SortTrigger = forwardRef(function SortTrigger( { sortKey, ...props }, @@ -62,13 +59,13 @@ const SortTrigger = forwardRef(funct ); }); -const MediaTypeTrigger = forwardRef(function MediaTypeTrigger( +const MediaTypeTrigger = forwardRef(function MediaTypeTrigger( { mediaType, ...props }, ref, ) { const { css } = useYoshiki(); const { t } = useTranslation(); - const labelKey = mediaType ? `browse.mediatypekey.${mediaType.key}` : "browse.mediatypelabel"; + const labelKey = mediaType !== MediaTypeAll ? `browse.mediatypekey.${mediaType.key}` : "browse.mediatypelabel"; return ( ; -} - export const BrowseSettings = ({ availableSorts, sortKey, @@ -102,8 +94,8 @@ export const BrowseSettings = ({ sortOrd: SortOrd; setSort: (sort: string, ord: SortOrd) => void; availableMediaTypes: MediaType[]; - mediaType?: MediaType; - setMediaType: (mediaType?: MediaType) => void; + mediaType: MediaType; + setMediaType: (mediaType: MediaType) => void; layout: Layout; setLayout: (layout: Layout) => void; }) => { @@ -164,13 +156,7 @@ export const BrowseSettings = ({ label={t(`browse.mediatypekey.${x.key}` as any)} selected={mediaType === x} icon={x.icon} - onSelect={() => { - if (mediaType === x || x === AllMediaTypes) { - setMediaType(undefined) - } else { - setMediaType(x) - } - }} + onSelect={() => setMediaType(x)} /> ))} diff --git a/front/packages/ui/src/browse/index.tsx b/front/packages/ui/src/browse/index.tsx index 5c5736b7..2ad96c77 100644 --- a/front/packages/ui/src/browse/index.tsx +++ b/front/packages/ui/src/browse/index.tsx @@ -32,7 +32,7 @@ import { DefaultLayout } from "../layout"; import { ItemGrid } from "./grid"; import { BrowseSettings } from "./header"; import { ItemList } from "./list"; -import {Layout, MediaTypes, SortBy, SortOrd} from "./types"; +import {MediaTypeAll, Layout, MediaTypes, SortBy, SortOrd, MediaTypeKey, MediaType} from "./types"; const { useParam } = createParam<{ sortBy?: string, mediaType?: string }>(); @@ -52,30 +52,38 @@ export const itemMap = ( item.kind === "show" ? item.watchStatus?.unseenEpisodesCount ?? item.episodesCount! : null, }); -const query = (sortKey?: SortBy, sortOrd?: SortOrd, mediaTypeKey?: string): QueryIdentifier => ({ - parser: LibraryItemP, - path: ["items"], - infinite: true, - params: { - sortBy: sortKey ? `${sortKey}:${sortOrd ?? "asc"}` : "name:asc", - filter: mediaTypeKey && mediaTypeKey !== "none" ? `kind eq ${mediaTypeKey}` : undefined, - fields: ["watchStatus", "episodesCount"], - }, -}); +const query = (mediaType: MediaType, sortKey?: SortBy, sortOrd?: SortOrd): QueryIdentifier => { + const filter = mediaType !== MediaTypeAll ? `kind eq ${mediaType.key}` : undefined; + return ({ + parser: LibraryItemP, + path: ["items"], + infinite: true, + params: { + sortBy: sortKey ? `${sortKey}:${sortOrd ?? "asc"}` : "name:asc", + filter, + fields: ["watchStatus", "episodesCount"], + }, + }); +} + +const getMediaTypeFromParam = (mediaTypeParam?: string): MediaType => { + const mediaTypeKey = mediaTypeParam as MediaTypeKey || MediaTypeKey.All; + return MediaTypes.find(t => t.key === mediaTypeKey) ?? MediaTypeAll; +} export const BrowsePage: QueryPage = () => { const [sort, setSort] = useParam("sortBy"); - const [mediaTypeKey, setMediaTypeKey] = useParam("mediaType"); + const [mediaTypeParam, setMediaTypeKey] = useParam("mediaType"); const sortKey = (sort?.split(":")[0] as SortBy) || SortBy.Name; const sortOrd = (sort?.split(":")[1] as SortOrd) || SortOrd.Asc; - const mediaType = mediaTypeKey !== undefined ? MediaTypes.find(t => t.key === mediaTypeKey) : undefined; const [layout, setLayout] = useState(Layout.Grid); + const mediaType = getMediaTypeFromParam(mediaTypeParam); const LayoutComponent = layout === Layout.Grid ? ItemGrid : ItemList; return ( { mediaType={mediaType} availableMediaTypes={MediaTypes} setMediaType={(mediaType) => { - setMediaTypeKey(mediaType?.key); + setMediaTypeKey(mediaType.key); }} layout={layout} setLayout={setLayout} @@ -102,6 +110,9 @@ export const BrowsePage: QueryPage = () => { BrowsePage.getLayout = DefaultLayout; -BrowsePage.getFetchUrls = ({ sortBy }) => [ - query(sortBy?.split("-")[0] as SortBy, sortBy?.split("-")[1] as SortOrd), -]; +BrowsePage.getFetchUrls = ({ mediaType, sortBy }) => { + const mediaTypeObj = getMediaTypeFromParam(mediaType); + return[ + query(mediaTypeObj, sortBy?.split("-")[0] as SortBy, sortBy?.split("-")[1] as SortOrd), + ]; +} diff --git a/front/packages/ui/src/browse/types.ts b/front/packages/ui/src/browse/types.ts index 8153b26f..b53de6e7 100644 --- a/front/packages/ui/src/browse/types.ts +++ b/front/packages/ui/src/browse/types.ts @@ -18,11 +18,12 @@ * along with Kyoo. If not, see . */ -import {MediaType} from "./header"; import Collection from "@material-symbols/svg-400/rounded/collections_bookmark.svg"; import TV from "@material-symbols/svg-400/rounded/tv.svg"; import Movie from "@material-symbols/svg-400/rounded/movie.svg"; import All from "@material-symbols/svg-400/rounded/view_headline.svg"; +import type {ComponentType} from "react"; +import type {SvgProps} from "react-native-svg"; export enum SortBy { Name = "name", @@ -49,23 +50,35 @@ export enum Layout { List, } -export const AllMediaTypes: MediaType = { - key: "all", +export enum MediaTypeKey{ + All = "all", + Movie = "movie", + Show = "show", + Collection = "collection", +} + +export interface MediaType { + key: MediaTypeKey; + icon: ComponentType; +} + +export const MediaTypeAll: MediaType = { + key: MediaTypeKey.All, icon: All } export const MediaTypes: MediaType[] = [ - AllMediaTypes, + MediaTypeAll, { - key: "movie", + key: MediaTypeKey.Movie, icon: Movie }, { - key: "show", + key: MediaTypeKey.Show, icon: TV, }, { - key: "collection", + key: MediaTypeKey.Collection, icon: Collection } ];