Tidy up based on review comments

This commit is contained in:
Scott Merchant 2024-06-09 10:40:00 +09:30 committed by Zoe Roux
parent b8db1fb151
commit 20963c021b
No known key found for this signature in database
3 changed files with 56 additions and 46 deletions

View File

@ -19,7 +19,6 @@
*/ */
import { import {
Chip,
HR, HR,
Icon, Icon,
IconButton, 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 ArrowUpward from "@material-symbols/svg-400/rounded/arrow_upward.svg";
import GridView from "@material-symbols/svg-400/rounded/grid_view.svg"; import GridView from "@material-symbols/svg-400/rounded/grid_view.svg";
import Sort from "@material-symbols/svg-400/rounded/sort.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 FilterList from "@material-symbols/svg-400/rounded/filter_list.svg";
import ViewList from "@material-symbols/svg-400/rounded/view_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 { useTranslation } from "react-i18next";
import { type PressableProps, View } from "react-native"; import { type PressableProps, View } from "react-native";
import { useYoshiki } from "yoshiki/native"; import { useYoshiki } from "yoshiki/native";
import {AllMediaTypes, Layout, SearchSort, SortOrd} from "./types"; import {Layout, MediaType, MediaTypeAll, SearchSort, SortOrd} from "./types";
import type {SvgProps} from "react-native-svg";
const SortTrigger = forwardRef<View, PressableProps & { sortKey: string }>(function SortTrigger( const SortTrigger = forwardRef<View, PressableProps & { sortKey: string }>(function SortTrigger(
{ sortKey, ...props }, { sortKey, ...props },
@ -62,13 +59,13 @@ const SortTrigger = forwardRef<View, PressableProps & { sortKey: string }>(funct
); );
}); });
const MediaTypeTrigger = forwardRef<View, PressableProps & { mediaType?: MediaType }>(function MediaTypeTrigger( const MediaTypeTrigger = forwardRef<View, PressableProps & { mediaType: MediaType }>(function MediaTypeTrigger(
{ mediaType, ...props }, { mediaType, ...props },
ref, ref,
) { ) {
const { css } = useYoshiki(); const { css } = useYoshiki();
const { t } = useTranslation(); const { t } = useTranslation();
const labelKey = mediaType ? `browse.mediatypekey.${mediaType.key}` : "browse.mediatypelabel"; const labelKey = mediaType !== MediaTypeAll ? `browse.mediatypekey.${mediaType.key}` : "browse.mediatypelabel";
return ( return (
<PressableFeedback <PressableFeedback
ref={ref} ref={ref}
@ -81,11 +78,6 @@ const MediaTypeTrigger = forwardRef<View, PressableProps & { mediaType?: MediaTy
); );
}); });
export interface MediaType {
key: string;
icon: ComponentType<SvgProps>;
}
export const BrowseSettings = ({ export const BrowseSettings = ({
availableSorts, availableSorts,
sortKey, sortKey,
@ -102,8 +94,8 @@ export const BrowseSettings = ({
sortOrd: SortOrd; sortOrd: SortOrd;
setSort: (sort: string, ord: SortOrd) => void; setSort: (sort: string, ord: SortOrd) => void;
availableMediaTypes: MediaType[]; availableMediaTypes: MediaType[];
mediaType?: MediaType; mediaType: MediaType;
setMediaType: (mediaType?: MediaType) => void; setMediaType: (mediaType: MediaType) => void;
layout: Layout; layout: Layout;
setLayout: (layout: Layout) => void; setLayout: (layout: Layout) => void;
}) => { }) => {
@ -164,13 +156,7 @@ export const BrowseSettings = ({
label={t(`browse.mediatypekey.${x.key}` as any)} label={t(`browse.mediatypekey.${x.key}` as any)}
selected={mediaType === x} selected={mediaType === x}
icon={x.icon} icon={x.icon}
onSelect={() => { onSelect={() => setMediaType(x)}
if (mediaType === x || x === AllMediaTypes) {
setMediaType(undefined)
} else {
setMediaType(x)
}
}}
/> />
))} ))}
</Menu> </Menu>

View File

@ -32,7 +32,7 @@ import { DefaultLayout } from "../layout";
import { ItemGrid } from "./grid"; import { ItemGrid } from "./grid";
import { BrowseSettings } from "./header"; import { BrowseSettings } from "./header";
import { ItemList } from "./list"; 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 }>(); const { useParam } = createParam<{ sortBy?: string, mediaType?: string }>();
@ -52,30 +52,38 @@ export const itemMap = (
item.kind === "show" ? item.watchStatus?.unseenEpisodesCount ?? item.episodesCount! : null, item.kind === "show" ? item.watchStatus?.unseenEpisodesCount ?? item.episodesCount! : null,
}); });
const query = (sortKey?: SortBy, sortOrd?: SortOrd, mediaTypeKey?: string): QueryIdentifier<LibraryItem> => ({ const query = (mediaType: MediaType, sortKey?: SortBy, sortOrd?: SortOrd): QueryIdentifier<LibraryItem> => {
const filter = mediaType !== MediaTypeAll ? `kind eq ${mediaType.key}` : undefined;
return ({
parser: LibraryItemP, parser: LibraryItemP,
path: ["items"], path: ["items"],
infinite: true, infinite: true,
params: { params: {
sortBy: sortKey ? `${sortKey}:${sortOrd ?? "asc"}` : "name:asc", sortBy: sortKey ? `${sortKey}:${sortOrd ?? "asc"}` : "name:asc",
filter: mediaTypeKey && mediaTypeKey !== "none" ? `kind eq ${mediaTypeKey}` : undefined, filter,
fields: ["watchStatus", "episodesCount"], 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 = () => { export const BrowsePage: QueryPage = () => {
const [sort, setSort] = useParam("sortBy"); 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 sortKey = (sort?.split(":")[0] as SortBy) || SortBy.Name;
const sortOrd = (sort?.split(":")[1] as SortOrd) || SortOrd.Asc; 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 [layout, setLayout] = useState(Layout.Grid);
const mediaType = getMediaTypeFromParam(mediaTypeParam);
const LayoutComponent = layout === Layout.Grid ? ItemGrid : ItemList; const LayoutComponent = layout === Layout.Grid ? ItemGrid : ItemList;
return ( return (
<InfiniteFetch <InfiniteFetch
query={query(sortKey, sortOrd, mediaTypeKey)} query={query(mediaType, sortKey, sortOrd)}
layout={LayoutComponent.layout} layout={LayoutComponent.layout}
Header={ Header={
<BrowseSettings <BrowseSettings
@ -88,7 +96,7 @@ export const BrowsePage: QueryPage = () => {
mediaType={mediaType} mediaType={mediaType}
availableMediaTypes={MediaTypes} availableMediaTypes={MediaTypes}
setMediaType={(mediaType) => { setMediaType={(mediaType) => {
setMediaTypeKey(mediaType?.key); setMediaTypeKey(mediaType.key);
}} }}
layout={layout} layout={layout}
setLayout={setLayout} setLayout={setLayout}
@ -102,6 +110,9 @@ export const BrowsePage: QueryPage = () => {
BrowsePage.getLayout = DefaultLayout; BrowsePage.getLayout = DefaultLayout;
BrowsePage.getFetchUrls = ({ sortBy }) => [ BrowsePage.getFetchUrls = ({ mediaType, sortBy }) => {
query(sortBy?.split("-")[0] as SortBy, sortBy?.split("-")[1] as SortOrd), const mediaTypeObj = getMediaTypeFromParam(mediaType);
]; return[
query(mediaTypeObj, sortBy?.split("-")[0] as SortBy, sortBy?.split("-")[1] as SortOrd),
];
}

View File

@ -18,11 +18,12 @@
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>. * along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {MediaType} from "./header";
import Collection from "@material-symbols/svg-400/rounded/collections_bookmark.svg"; import Collection from "@material-symbols/svg-400/rounded/collections_bookmark.svg";
import TV from "@material-symbols/svg-400/rounded/tv.svg"; import TV from "@material-symbols/svg-400/rounded/tv.svg";
import Movie from "@material-symbols/svg-400/rounded/movie.svg"; import Movie from "@material-symbols/svg-400/rounded/movie.svg";
import All from "@material-symbols/svg-400/rounded/view_headline.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 { export enum SortBy {
Name = "name", Name = "name",
@ -49,23 +50,35 @@ export enum Layout {
List, List,
} }
export const AllMediaTypes: MediaType = { export enum MediaTypeKey{
key: "all", All = "all",
Movie = "movie",
Show = "show",
Collection = "collection",
}
export interface MediaType {
key: MediaTypeKey;
icon: ComponentType<SvgProps>;
}
export const MediaTypeAll: MediaType = {
key: MediaTypeKey.All,
icon: All icon: All
} }
export const MediaTypes: MediaType[] = [ export const MediaTypes: MediaType[] = [
AllMediaTypes, MediaTypeAll,
{ {
key: "movie", key: MediaTypeKey.Movie,
icon: Movie icon: Movie
}, },
{ {
key: "show", key: MediaTypeKey.Show,
icon: TV, icon: TV,
}, },
{ {
key: "collection", key: MediaTypeKey.Collection,
icon: Collection icon: Collection
} }
]; ];