Handle multi video entries

This commit is contained in:
Zoe Roux
2026-01-30 19:28:29 +01:00
parent 3c106844aa
commit 65756e2e1c
7 changed files with 130 additions and 51 deletions
+42 -40
View File
@@ -1,5 +1,4 @@
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 MultipleVideos from "@material-symbols/svg-400/rounded/subscriptions-fill.svg";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { type PressableProps, View } from "react-native";
@@ -7,12 +6,13 @@ import { EntryContext } from "~/components/items/context-menus";
import { ItemProgress } from "~/components/items/item-grid";
import type { KImage } from "~/models";
import {
CroppedText,
Heading,
IconButton,
Icon,
Image,
ImageBackground,
Link,
P,
PressableFeedback,
Skeleton,
SubP,
tooltip,
@@ -35,6 +35,7 @@ export const EntryLine = ({
watchedPercent,
href,
className,
videosCount,
...props
}: {
slug: string;
@@ -50,9 +51,9 @@ export const EntryLine = ({
runtime: number | null;
watchedPercent: number | null;
href: string | null;
videosCount: number;
} & PressableProps) => {
const [moreOpened, setMoreOpened] = useState(false);
const [descriptionExpanded, setDescriptionExpanded] = useState(false);
const { t } = useTranslation();
return (
@@ -71,7 +72,7 @@ export const EntryLine = ({
quality="low"
alt=""
className={cn(
"m-1 w-1/5 shrink-0 rounded",
"mr-1 w-1/5 shrink-0 rounded",
poster ? "aspect-2/3" : "aspect-video",
"group-hover:ring-3 group-hover:ring-accent group-focus-visible:ring-3 group-focus-visible:ring-accent",
)}
@@ -81,12 +82,12 @@ export const EntryLine = ({
)}
</ImageBackground>
<View className="m-1 mx-2 flex-1">
<View className="flex-1 flex-row justify-between">
<View className="mb-5 flex-1">
<View className="mb-5 flex-1 flex-row">
<View className="flex-1 flex-row items-center">
<Heading
className={cn(
"font-medium group-hover:underline group-focus-visible:underline",
"text-lg",
"shrink font-medium text-lg",
"group-hover:underline group-focus-visible:underline",
)}
>
{[displayNumber, name ?? t("show.episodeNoMetadata")]
@@ -95,47 +96,48 @@ export const EntryLine = ({
</Heading>
{tagline && <Heading>{tagline}</Heading>}
</View>
<View className="flex-row items-center">
<SubP>
{[
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(" · ")}
</SubP>
<View className="flex-row">
<View className="flex-col-reverse justify-end md:flex-row md:items-center">
{videosCount > 1 && (
<PressableFeedback
className="flex-row items-center rounded-2xl bg-popover p-2 md:mx-4"
{...tooltip(t("show.multiVideos"))}
>
<Icon
icon={MultipleVideos}
fillClassName="accent-accent dark:accent-slate-400"
/>
<SubP className="ml-2">
{t("show.videosCount", { number: videosCount })}
</SubP>
</PressableFeedback>
)}
<SubP>
{[
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(" · ")}
</SubP>
</View>
<EntryContext
slug={slug}
serieSlug={serieSlug}
isOpen={moreOpened}
setOpen={(v) => setMoreOpened(v)}
className={cn(
"ml-3 flex",
"not:web:opacity-100 opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
"ml-3 flex native:hidden",
"opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100",
moreOpened && "opacity-100",
)}
/>
</View>
</View>
<View className="flex-row justify-between">
<P numberOfLines={descriptionExpanded ? undefined : 3}>
{description}
</P>
<IconButton
className="not:web:opacity-100 opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100"
icon={descriptionExpanded ? ExpandLess : ExpandMore}
{...tooltip(
t(descriptionExpanded ? "misc.collapse" : "misc.expand"),
)}
onPress={(e) => {
e.preventDefault();
setDescriptionExpanded((isExpanded) => !isExpanded);
}}
/>
</View>
<CroppedText numberOfLines={3}>{description}</CroppedText>
</View>
</Link>
);