mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-05-22 15:12:28 -04:00
Handle multi video entries
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user