Add movie watch percent progress bar

This commit is contained in:
Zoe Roux 2023-12-06 15:11:50 +01:00
parent c87001d91e
commit e2414f94f3
7 changed files with 47 additions and 21 deletions

View File

@ -233,6 +233,7 @@ public class WatchStatusRepository : IWatchStatusRepository
MovieId = movieId, MovieId = movieId,
Status = status, Status = status,
WatchedTime = watchedTime, WatchedTime = watchedTime,
WatchedPercent = percent,
AddedDate = DateTime.UtcNow, AddedDate = DateTime.UtcNow,
PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null, PlayedDate = status == WatchStatus.Completed ? DateTime.UtcNow : null,
}; };

View File

@ -64,6 +64,7 @@ export const ImageBackground = <AsProps = ViewProps,>({
imageStyle, imageStyle,
forcedLoading, forcedLoading,
hideLoad = true, hideLoad = true,
contrast = "dark",
layout, layout,
...asProps ...asProps
}: { }: {
@ -73,12 +74,13 @@ export const ImageBackground = <AsProps = ViewProps,>({
containerStyle?: YoshikiEnhanced<ViewStyle>; containerStyle?: YoshikiEnhanced<ViewStyle>;
imageStyle?: YoshikiEnhanced<ImageStyle>; imageStyle?: YoshikiEnhanced<ImageStyle>;
hideLoad?: boolean; hideLoad?: boolean;
contrast?: "light" | "dark" | "user";
layout?: ImageLayout; layout?: ImageLayout;
} & AsProps & } & AsProps &
Props) => { Props) => {
const Container = as ?? View; const Container = as ?? View;
return ( return (
<ContrastArea contrastText> <ContrastArea contrastText mode={contrast}>
{({ css, theme }) => ( {({ css, theme }) => (
<Container <Container
{...(css( {...(css(

View File

@ -65,13 +65,42 @@ export const ItemWatchStatus = ({
); );
}; };
export const ItemProgress = ({ watchPercent }: { watchPercent: number }) => {
const { css } = useYoshiki("episodebox");
return (
<>
<View
{...css({
backgroundColor: (theme) => theme.user.overlay0,
width: percent(100),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
/>
<View
{...css({
backgroundColor: (theme) => theme.user.accent,
width: percent(watchPercent),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
/>
</>
);
};
export const ItemGrid = ({ export const ItemGrid = ({
href, href,
name, name,
type,
subtitle, subtitle,
poster, poster,
isLoading, isLoading,
watchStatus, watchStatus,
watchPercent,
unseenEpisodesCount, unseenEpisodesCount,
...props ...props
}: WithLoading<{ }: WithLoading<{
@ -80,6 +109,8 @@ export const ItemGrid = ({
subtitle?: string; subtitle?: string;
poster?: KyooImage | null; poster?: KyooImage | null;
watchStatus: WatchStatusV | null; watchStatus: WatchStatusV | null;
watchPercent: number | null;
type: "movie" | "show" | "collection";
unseenEpisodesCount: number | null; unseenEpisodesCount: number | null;
}> & }> &
Stylable<"text">) => { Stylable<"text">) => {
@ -122,6 +153,7 @@ export const ItemGrid = ({
{...(css("poster") as { style: ImageStyle })} {...(css("poster") as { style: ImageStyle })}
> >
<ItemWatchStatus watchStatus={watchStatus} unseenEpisodesCount={unseenEpisodesCount} /> <ItemWatchStatus watchStatus={watchStatus} unseenEpisodesCount={unseenEpisodesCount} />
{type === "movie" && watchPercent && <ItemProgress watchPercent={watchPercent} />}
</PosterBackground> </PosterBackground>
<Skeleton> <Skeleton>
{isLoading || ( {isLoading || (

View File

@ -51,6 +51,9 @@ export const itemMap = (
poster: item.poster, poster: item.poster,
thumbnail: item.thumbnail, thumbnail: item.thumbnail,
watchStatus: item.kind !== ItemKind.Collection ? item.watchStatus?.status ?? null : null, watchStatus: item.kind !== ItemKind.Collection ? item.watchStatus?.status ?? null : null,
type: item.kind.toLowerCase() as any,
watchPercent:
item.kind !== ItemKind.Collection ? item.watchStatus?.watchedPercent ?? null : null,
unseenEpisodesCount: unseenEpisodesCount:
item.kind === ItemKind.Show item.kind === ItemKind.Show
? item.watchStatus?.unseenEpisodesCount ?? item.episodesCount! ? item.watchStatus?.unseenEpisodesCount ?? item.episodesCount!

View File

@ -34,6 +34,7 @@ import { ImageStyle, View } from "react-native";
import { Layout, WithLoading } from "../fetch"; import { Layout, WithLoading } from "../fetch";
import { percent, rem, Stylable, Theme, useYoshiki } from "yoshiki/native"; import { percent, rem, Stylable, Theme, useYoshiki } from "yoshiki/native";
import { KyooImage, WatchStatusV } from "@kyoo/models"; import { KyooImage, WatchStatusV } from "@kyoo/models";
import { ItemProgress } from "../browse/grid";
export const episodeDisplayNumber = ( export const episodeDisplayNumber = (
episode: { episode: {
@ -112,26 +113,7 @@ export const EpisodeBox = ({
{...(css("poster") as any)} {...(css("poster") as any)}
> >
{(watchedPercent || watchedStatus === WatchStatusV.Completed) && ( {(watchedPercent || watchedStatus === WatchStatusV.Completed) && (
<> <ItemProgress watchPercent={watchedPercent ?? 100} />
<View
{...css({
backgroundColor: (theme) => theme.overlay0,
width: percent(100),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
/>
<View
{...css({
backgroundColor: (theme) => theme.accent,
width: percent(watchedPercent ?? 100),
height: ts(0.5),
position: "absolute",
bottom: 0,
})}
/>
</>
)} )}
</ImageBackground> </ImageBackground>
<Skeleton {...css({ width: percent(50) })}> <Skeleton {...css({ width: percent(50) })}>

View File

@ -49,6 +49,9 @@ export const NewsList = () => {
name={x.name!} name={x.name!}
subtitle={!x.isLoading ? getDisplayDate(x) : undefined} subtitle={!x.isLoading ? getDisplayDate(x) : undefined}
poster={x.poster} poster={x.poster}
watchStatus={x.watchStatus?.status || null}
watchPercent={x.watchStatus?.watchedPercent || null}
type={"movie"}
/> />
) : ( ) : (
<EpisodeBox <EpisodeBox

View File

@ -72,6 +72,9 @@ export const WatchlistList = () => {
name={x.name!} name={x.name!}
subtitle={!x.isLoading ? getDisplayDate(x) : undefined} subtitle={!x.isLoading ? getDisplayDate(x) : undefined}
poster={x.poster} poster={x.poster}
watchStatus={x.watchStatus?.status || null}
watchPercent={x.watchStatus?.watchedPercent || null}
type={x.kind === WatchlistKind.Movie ? "movie" : "show"}
/> />
); );
}} }}