import ExpandMore from "@material-symbols/svg-400/rounded/keyboard_arrow_down-fill.svg"; import ExpandLess from "@material-symbols/svg-400/rounded/keyboard_arrow_up-fill.svg"; import { useState } from "react"; import { useTranslation } from "react-i18next"; 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 } from "~/models"; import { focusReset, H6, IconButton, Image, ImageBackground, important, Link, P, Skeleton, SubP, tooltip, ts, } from "~/primitives"; import type { Layout } from "~/query"; import { displayRuntime } from "~/utils"; export const EntryLine = ({ slug, serieSlug, name, thumbnail, description, displayNumber, airDate, runtime, watchedPercent, href, ...props }: { slug: string; // if show slug is null, disable "Go to show" in the context menu serieSlug: string | null; displayNumber: string; name: string | null; description: string | null; thumbnail: KImage | null; airDate: Date | null; runtime: number | null; watchedPercent: number | null; href: string | null; } & PressableProps) => { const [moreOpened, setMoreOpened] = useState(false); const [descriptionExpanded, setDescriptionExpanded] = useState(false); const { css } = useYoshiki("episode-line"); const { t } = useTranslation(); return ( setMoreOpened(true)} {...css( { alignItems: "center", flexDirection: "row", child: { more: { opacity: 0, }, }, fover: { self: focusReset, title: { textDecorationLine: "underline", }, more: { opacity: 1, }, }, }, props, )} > {watchedPercent && ( )} {/* biome-ignore lint/a11y/useValidAriaValues: simply use H6 for the style but keep a P */}
{[displayNumber, name ?? t("show.episodeNoMetadata")].join(" · ")}
{[ airDate ? // @ts-expect-error Source https://www.i18next.com/translation-function/formatting#datetime t("{{val, datetime}}", { val: airDate }) : null, displayRuntime(runtime), ] .filter((item) => item != null) .join(" · ")} setMoreOpened(v)} {...css([ "more", { display: "flex", marginLeft: ts(3) }, Platform.OS === "web" && moreOpened && { display: important("flex") }, ])} />

{description}

{ e.preventDefault(); setDescriptionExpanded((isExpanded) => !isExpanded); }} />
); }; EntryLine.Loader = (props: Stylable) => { const { css } = useYoshiki(); return ( ); }; EntryLine.layout = { numColumns: 1, size: 100, layout: "vertical", gap: ts(1), } satisfies Layout;