Make series page

This commit is contained in:
Zoe Roux
2025-07-14 22:59:55 +02:00
parent d5c7ee40bc
commit 42cce837e4
11 changed files with 138 additions and 180 deletions
@@ -6,7 +6,7 @@ import { Platform, type PressableProps, View } from "react-native";
import { percent, type Stylable, useYoshiki } from "yoshiki/native";
import { EntryContext } from "~/components/items/context-menus";
import { ItemProgress } from "~/components/items/item-grid";
import type { KImage, WatchStatusV } from "~/models";
import type { KImage } from "~/models";
import {
focusReset,
H6,
@@ -34,7 +34,6 @@ export const EntryLine = ({
airDate,
runtime,
watchedPercent,
watchedStatus,
href,
...props
}: {
@@ -48,7 +47,6 @@ export const EntryLine = ({
airDate: Date | null;
runtime: number | null;
watchedPercent: number | null;
watchedStatus: WatchStatusV | null;
href: string;
} & PressableProps) => {
const [moreOpened, setMoreOpened] = useState(false);
@@ -92,7 +90,7 @@ export const EntryLine = ({
}}
{...(css({ flexShrink: 0, m: ts(1), borderRadius: 6 }) as any)}
>
{(watchedPercent || watchedStatus === "completed") && (
{watchedPercent && (
<ItemProgress watchPercent={watchedPercent ?? 100} />
)}
</ImageBackground>
@@ -124,7 +122,6 @@ export const EntryLine = ({
<EntryContext
slug={slug}
serieSlug={serieSlug}
status={watchedStatus}
isOpen={moreOpened}
setOpen={(v) => setMoreOpened(v)}
{...css([
+15 -14
View File
@@ -1,16 +1,17 @@
export * from "./entry-box";
export * from "./entry-list";
import type { Entry } from "~/models";
export const episodeDisplayNumber = (episode: {
seasonNumber?: number | null;
episodeNumber?: number | null;
absoluteNumber?: number | null;
}) => {
if (
typeof episode.seasonNumber === "number" &&
typeof episode.episodeNumber === "number"
)
return `S${episode.seasonNumber}:E${episode.episodeNumber}`;
if (episode.absoluteNumber) return episode.absoluteNumber.toString();
return "??";
export * from "./entry-box";
export * from "./entry-line";
export const entryDisplayNumber = (entry: Entry) => {
switch (entry.kind) {
case "episode":
return `S${entry.seasonNumber}:E${entry.episodeNumber}`;
case "special":
return `SP${entry.number}`
case "movie":
return "";
default:
return "??";
}
};
+47 -41
View File
@@ -15,14 +15,54 @@ import { watchListIcon } from "./watchlist-info";
// import { useDownloader } from "../../packages/ui/src/downloadses/ui/src/downloads";
export const EntryContext = ({
kind = "entry",
slug,
serieSlug,
...props
}: {
serieSlug: string | null;
slug: string;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
// const downloader = useDownloader();
const { css } = useYoshiki();
const { t } = useTranslation();
return (
<>
<Menu
Trigger={IconButton}
icon={MoreVert}
{...tooltip(t("misc.more"))}
{...(css([Platform.OS !== "web" && { display: "none" }], props) as any)}
>
{serieSlug && (
<Menu.Item
label={t("home.episodeMore.goToShow")}
icon={Info}
href={`/series/${serieSlug}`}
/>
)}
{/* <Menu.Item */}
{/* label={t("home.episodeMore.download")} */}
{/* icon={Download} */}
{/* onSelect={() => downloader(type, slug)} */}
{/* /> */}
<Menu.Item
label={t("home.episodeMore.mediainfo")}
icon={MovieInfo}
href={`/entries/${slug}/info`}
/>
</Menu>
</>
);
};
export const ItemContext = ({
kind,
slug,
status,
...props
}: {
kind?: "serie" | "movie" | "entry";
serieSlug?: string | null;
kind: "movie" | "serie";
slug: string;
status: WatchStatusV | null;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
@@ -32,10 +72,7 @@ export const EntryContext = ({
const { t } = useTranslation();
const mutation = useMutation({
path:
kind === "entry"
? ["serie", serieSlug!, "entries", slug]
: [kind, slug, "watchStatus"],
path: [kind, slug, "watchStatus"],
compute: (newStatus: WatchStatusV | null) => ({
method: newStatus ? "POST" : "DELETE",
params: newStatus ? { status: newStatus } : undefined,
@@ -55,18 +92,8 @@ export const EntryContext = ({
Trigger={IconButton}
icon={MoreVert}
{...tooltip(t("misc.more"))}
{...(css(
[Platform.OS !== "web" && { display: "none" }],
props,
) as any)}
{...(css([Platform.OS !== "web" && { display: "none" }], props) as any)}
>
{serieSlug && (
<Menu.Item
label={t("home.episodeMore.goToShow")}
icon={Info}
href={`/serie/${serieSlug}`}
/>
)}
<Menu.Sub
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")}
disabled={!account}
@@ -89,7 +116,7 @@ export const EntryContext = ({
/>
)}
</Menu.Sub>
{kind !== "serie" && (
{kind === "movie" && (
<>
{/* <Menu.Item */}
{/* label={t("home.episodeMore.download")} */}
@@ -99,7 +126,7 @@ export const EntryContext = ({
<Menu.Item
label={t("home.episodeMore.mediainfo")}
icon={MovieInfo}
href={`/${kind}/${slug}/info`}
href={`/movies/${slug}/info`}
/>
</>
)}
@@ -117,24 +144,3 @@ export const EntryContext = ({
</>
);
};
export const ItemContext = ({
kind,
slug,
status,
...props
}: {
kind: "movie" | "serie";
slug: string;
status: WatchStatusV | null;
} & Partial<ComponentProps<typeof Menu<typeof IconButton>>>) => {
return (
<EntryContext
kind={kind}
slug={slug}
status={status}
serieSlug={null}
{...props}
/>
);
};