Create a component for watch status overlay

This commit is contained in:
Zoe Roux 2023-12-05 01:59:34 +01:00
parent ce07cece06
commit 0294f538eb
3 changed files with 46 additions and 77 deletions

View File

@ -19,21 +19,52 @@
*/ */
import { KyooImage, WatchStatusV } from "@kyoo/models"; import { KyooImage, WatchStatusV } from "@kyoo/models";
import { import { Link, Skeleton, ts, focusReset, P, SubP, PosterBackground, Icon } from "@kyoo/primitives";
Link,
Skeleton,
ts,
focusReset,
P,
SubP,
PosterBackground,
Icon,
} from "@kyoo/primitives";
import { ImageStyle, View } from "react-native"; import { ImageStyle, View } from "react-native";
import { percent, px, Stylable, Theme, useYoshiki } from "yoshiki/native"; import { percent, px, Stylable, Theme, useYoshiki } from "yoshiki/native";
import { Layout, WithLoading } from "../fetch"; import { Layout, WithLoading } from "../fetch";
import Done from "@material-symbols/svg-400/rounded/done-fill.svg"; import Done from "@material-symbols/svg-400/rounded/done-fill.svg";
export const ItemWatchStatus = ({
watchStatus,
unseenEpisodesCount,
...props
}: {
watchStatus?: WatchStatusV | null;
unseenEpisodesCount?: number | null;
}) => {
const { css } = useYoshiki();
if (watchStatus !== WatchStatusV.Completed && !unseenEpisodesCount) return null;
return (
<View
{...css(
{
position: "absolute",
top: 0,
right: 0,
minWidth: ts(3.5),
aspectRatio: 1,
justifyContent: "center",
alignItems: "center",
m: ts(0.5),
pX: ts(0.5),
bg: (theme) => theme.darkOverlay,
borderRadius: 999999,
},
props,
)}
>
{watchStatus === WatchStatusV.Completed ? (
<Icon icon={Done} size={16} />
) : (
<P {...css({ m: 0, textAlign: "center" })}>{unseenEpisodesCount}</P>
)}
</View>
);
};
export const ItemGrid = ({ export const ItemGrid = ({
href, href,
name, name,
@ -90,28 +121,7 @@ export const ItemGrid = ({
layout={{ width: percent(100) }} layout={{ width: percent(100) }}
{...(css("poster") as { style: ImageStyle })} {...(css("poster") as { style: ImageStyle })}
> >
{(watchStatus === WatchStatusV.Completed || unseenEpisodesCount) && ( <ItemWatchStatus watchStatus={watchStatus} unseenEpisodesCount={unseenEpisodesCount} />
<View
{...css({
position: "absolute",
top: 0,
right: 0,
minWidth: ts(3.5),
aspectRatio: 1,
justifyContent: "center",
m: ts(0.5),
pX: ts(0.5),
bg: (theme) => theme.darkOverlay,
borderRadius: 999999,
})}
>
{watchStatus === WatchStatusV.Completed ? (
<Icon icon={Done} size={16} />
) : (
<P {...css({ m: 0, textAlign: "center" })}>{unseenEpisodesCount}</P>
)}
</View>
)}
</PosterBackground> </PosterBackground>
<Skeleton> <Skeleton>
{isLoading || ( {isLoading || (

View File

@ -35,6 +35,7 @@ import { View } from "react-native";
import { percent, px, rem, useYoshiki } from "yoshiki/native"; import { percent, px, rem, useYoshiki } from "yoshiki/native";
import { Layout, WithLoading } from "../fetch"; import { Layout, WithLoading } from "../fetch";
import Done from "@material-symbols/svg-400/rounded/done-fill.svg"; import Done from "@material-symbols/svg-400/rounded/done-fill.svg";
import { ItemWatchStatus } from "./grid";
export const ItemList = ({ export const ItemList = ({
href, href,
@ -130,28 +131,7 @@ export const ItemList = ({
forcedLoading={isLoading} forcedLoading={isLoading}
layout={{ height: percent(80) }} layout={{ height: percent(80) }}
> >
{(watchStatus === WatchStatusV.Completed || unseenEpisodesCount) && ( <ItemWatchStatus watchStatus={watchStatus} unseenEpisodesCount={unseenEpisodesCount} />
<View
{...css({
position: "absolute",
top: 0,
left: 0,
minWidth: ts(3.5),
aspectRatio: 1,
justifyContent: "center",
m: ts(0.5),
pX: ts(0.5),
bg: (theme) => theme.darkOverlay,
borderRadius: 999999,
})}
>
{watchStatus === WatchStatusV.Completed ? (
<Icon icon={Done} size={16} />
) : (
<P {...css({ m: 0, textAlign: "center" })}>{unseenEpisodesCount}</P>
)}
</View>
)}
</PosterBackground> </PosterBackground>
</ImageBackground> </ImageBackground>
); );

View File

@ -49,7 +49,7 @@ import { Theme, percent, px, rem, useYoshiki } from "yoshiki/native";
import { Layout, WithLoading } from "../fetch"; import { Layout, WithLoading } from "../fetch";
import { InfiniteFetch } from "../fetch-infinite"; import { InfiniteFetch } from "../fetch-infinite";
import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg"; import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg";
import { ItemGrid } from "../browse/grid"; import { ItemGrid, ItemWatchStatus } from "../browse/grid";
import Done from "@material-symbols/svg-400/rounded/done-fill.svg"; import Done from "@material-symbols/svg-400/rounded/done-fill.svg";
export const ItemDetails = ({ export const ItemDetails = ({
@ -133,28 +133,7 @@ export const ItemDetails = ({
</Skeleton> </Skeleton>
)} )}
</View> </View>
{(watchStatus === WatchStatusV.Completed || unseenEpisodesCount) && ( <ItemWatchStatus watchStatus={watchStatus} unseenEpisodesCount={unseenEpisodesCount} />
<View
{...css({
position: "absolute",
top: 0,
right: 0,
minWidth: ts(3.5),
aspectRatio: 1,
justifyContent: "center",
m: ts(0.5),
pX: ts(0.5),
bg: (theme) => theme.darkOverlay,
borderRadius: 999999,
})}
>
{watchStatus === WatchStatusV.Completed ? (
<Icon icon={Done} size={16} />
) : (
<P {...css({ m: 0, textAlign: "center" })}>{unseenEpisodesCount}</P>
)}
</View>
)}
</PosterBackground> </PosterBackground>
<View {...css({ flexShrink: 1, flexGrow: 1, justifyContent: "flex-end" })}> <View {...css({ flexShrink: 1, flexGrow: 1, justifyContent: "flex-end" })}>
{(isLoading || tagline) && ( {(isLoading || tagline) && (