From 3bfadc673e1a76d191bbe62ad7667acbccc71c1d Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 3 Feb 2026 23:17:17 +0100 Subject: [PATCH] Type error cleanups --- front/src/components/entries/entry-box.tsx | 10 +- front/src/components/items/index.ts | 4 +- front/src/components/items/item-grid.tsx | 12 +- front/src/components/items/item-helpers.tsx | 43 +--- front/src/components/items/item-list.tsx | 213 +++++++------------- front/src/primitives/avatar.tsx | 22 +- front/src/primitives/button.tsx | 2 +- front/src/primitives/icons.tsx | 4 +- front/src/primitives/image-background.tsx | 39 ---- front/src/primitives/select.tsx | 7 +- front/src/ui/details/header.tsx | 11 +- front/src/ui/home/header.tsx | 123 +++++------ front/src/ui/home/recommended.tsx | 9 +- front/src/ui/home/watchlist.tsx | 2 +- front/src/ui/settings/account.tsx | 3 - 15 files changed, 172 insertions(+), 332 deletions(-) diff --git a/front/src/components/entries/entry-box.tsx b/front/src/components/entries/entry-box.tsx index a9f93f43..57a8c193 100644 --- a/front/src/components/entries/entry-box.tsx +++ b/front/src/components/entries/entry-box.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { View } from "react-native"; -import type { KImage, WatchStatusV } from "~/models"; +import type { KImage } from "~/models"; import { Image, ImageBackground, @@ -24,7 +24,6 @@ export const EntryBox = ({ thumbnail, href, watchedPercent, - watchedStatus, className, ...props }: { @@ -35,8 +34,7 @@ export const EntryBox = ({ description: string | null; href: string; thumbnail: KImage | null; - watchedPercent: number | null; - watchedStatus: WatchStatusV | null; + watchedPercent: number; className?: string; }) => { const [moreOpened, setMoreOpened] = useState(false); @@ -58,9 +56,7 @@ export const EntryBox = ({ "ring-accent group-hover:ring-3 group-focus-visible:ring-3", )} > - {(watchedPercent || watchedStatus === "completed") && ( - - )} + { + if (!watchPercent) return null; return ( <> @@ -36,7 +37,8 @@ export const ItemGrid = ({ poster, watchStatus, watchPercent, - unseenEpisodesCount, + availableCount, + seenCount, horizontal = false, className, ...props @@ -49,8 +51,9 @@ export const ItemGrid = ({ watchStatus: WatchStatusV | null; watchPercent: number | null; kind: "movie" | "serie" | "collection"; - unseenEpisodesCount: number | null; - horizontal: boolean; + availableCount?: number | null; + seenCount?: number | null; + horizontal?: boolean; className?: string; }) => { const [moreOpened, setMoreOpened] = useState(false); @@ -77,7 +80,8 @@ export const ItemGrid = ({ > {kind === "movie" && watchPercent && ( diff --git a/front/src/components/items/item-helpers.tsx b/front/src/components/items/item-helpers.tsx index da2c48fe..501fff2e 100644 --- a/front/src/components/items/item-helpers.tsx +++ b/front/src/components/items/item-helpers.tsx @@ -1,51 +1,30 @@ import Done from "@material-symbols/svg-400/rounded/check-fill.svg"; import { View } from "react-native"; -import { max, rem, useYoshiki } from "yoshiki/native"; import type { WatchStatusV } from "~/models"; -import { Icon, P, ts } from "~/primitives"; +import { Icon, P } from "~/primitives"; export const ItemWatchStatus = ({ watchStatus, - unseenEpisodesCount, + availableCount, + seenCount, ...props }: { watchStatus?: WatchStatusV | null; - unseenEpisodesCount?: number | null; + availableCount?: number | null; + seenCount?: number | null; }) => { - const { css } = useYoshiki(); - - if (watchStatus !== "completed" && !unseenEpisodesCount) return null; + if (watchStatus !== "completed" && !availableCount) return null; return ( theme.darkOverlay, - borderRadius: 999999, - }, - props, - )} + className="absolute top-0 right-0 m-1 aspect-square min-w-8 items-center justify-center rounded-full bg-gray-800/70 p-1" + {...props} > {watchStatus === "completed" ? ( - + ) : ( -

- {unseenEpisodesCount} +

+ {seenCount ?? 0}/{availableCount}

)}
diff --git a/front/src/components/items/item-list.tsx b/front/src/components/items/item-list.tsx index 8a16fb51..2a0172f5 100644 --- a/front/src/components/items/item-list.tsx +++ b/front/src/components/items/item-list.tsx @@ -1,12 +1,9 @@ import { useState } from "react"; -import { Platform, View } from "react-native"; -import { percent, px, rem, useYoshiki } from "yoshiki/native"; +import { View } from "react-native"; import type { KImage, WatchStatusV } from "~/models"; import { - ContrastArea, - GradientImageBackground, Heading, - important, + ImageBackground, Link, P, Poster, @@ -15,6 +12,7 @@ import { ts, } from "~/primitives"; import type { Layout } from "~/query"; +import { cn } from "~/utils"; import { ItemContext } from "./context-menus"; import { ItemWatchStatus } from "./item-helpers"; @@ -27,7 +25,9 @@ export const ItemList = ({ thumbnail, poster, watchStatus, - unseenEpisodesCount, + availableCount, + seenCount, + className, ...props }: { href: string; @@ -38,159 +38,92 @@ export const ItemList = ({ poster: KImage | null; thumbnail: KImage | null; watchStatus: WatchStatusV | null; - unseenEpisodesCount: number | null; + availableCount?: number | null; + seenCount?: number | null; + className?: string; }) => { const [moreOpened, setMoreOpened] = useState(false); return ( - - {({ css }) => ( - setMoreOpened(true)} - {...css({ - child: { - more: { - opacity: 0, - }, - }, - fover: { - title: { - textDecorationLine: "underline", - }, - more: { - opacity: 100, - }, - }, - })} - {...props} - > - - - - - {name} - - {kind !== "collection" && ( - setMoreOpened(v)} - {...css([ - { - // I dont know why marginLeft gets overwritten by the margin: px(2) so we important - marginLeft: important(ts(2)), - bg: (theme) => theme.darkOverlay, - }, - "more", - Platform.OS === "web" && - moreOpened && { opacity: important(100) }, - ])} - /> - )} - - {subtitle && ( -

- {subtitle} -

- )} -
- - - -
- + setMoreOpened(true)} + className={cn( + "group h-80 w-full outline-0 ring-accent focus-within:ring-3 hover:ring-3", + className, )} -
+ {...props} + > + + + + + + {name} + + {kind !== "collection" && ( + setMoreOpened(v)} + className={cn( + "ml-4", + "bg-gray-800/70 hover:bg-gray-800 focus-visible:bg-gray-800", + "native:hidden opacity-0 focus-visible:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100", + moreOpened && "opacity-100", + )} + iconClassName="fill-slate-200 dark:fill-slate-200" + /> + )} + + {subtitle &&

{subtitle}

} +
+ + + +
+ ); }; ItemList.Loader = (props: object) => { - const { css } = useYoshiki(); - return ( theme.dark.background, - marginX: ItemList.layout.gap, - }, - props, - )} + className="h-80 w-full flex-row items-center justify-evenly overflow-hidden rounded bg-slate-800" + {...props} > - - - + + + - + ); }; ItemList.layout = { numColumns: 1, - size: 300, + size: 320, layout: "vertical", gap: ts(2), } satisfies Layout; diff --git a/front/src/primitives/avatar.tsx b/front/src/primitives/avatar.tsx index df0602ce..d8e5af2a 100644 --- a/front/src/primitives/avatar.tsx +++ b/front/src/primitives/avatar.tsx @@ -1,8 +1,10 @@ +import AccountCircle from "@material-symbols/svg-400/rounded/account_circle-fill.svg"; import type { ComponentType } from "react"; import { Image, View, type ViewProps, type ViewStyle } from "react-native"; import { cn } from "~/utils"; import { Skeleton } from "./skeleton"; import { P } from "./text"; +import { Icon } from "./icons"; const stringToColor = (string: string) => { let hash = 0; @@ -51,12 +53,20 @@ export const Avatar = ({ {placeholder[0]}

)} - {alt} + {src && ( + {alt} + )} + {!src && !placeholder && ( + + )} ); }; diff --git a/front/src/primitives/button.tsx b/front/src/primitives/button.tsx index 6a62d168..15aff478 100644 --- a/front/src/primitives/button.tsx +++ b/front/src/primitives/button.tsx @@ -35,7 +35,7 @@ export const Button = ({ disabled={disabled} className={cn( "flex-row items-center justify-center overflow-hidden", - "rounded-4xl border-3 border-accent p-1", + "rounded-4xl border-3 border-accent p-1 outline-0", disabled && "border-slate-600", "group focus-within:bg-accent hover:bg-accent", className, diff --git a/front/src/primitives/icons.tsx b/front/src/primitives/icons.tsx index baa80d70..8d318a2d 100644 --- a/front/src/primitives/icons.tsx +++ b/front/src/primitives/icons.tsx @@ -124,8 +124,8 @@ export const IconFab = ({ diff --git a/front/src/primitives/image-background.tsx b/front/src/primitives/image-background.tsx index 235e8ce2..fc3b34f4 100644 --- a/front/src/primitives/image-background.tsx +++ b/front/src/primitives/image-background.tsx @@ -1,10 +1,8 @@ import { ImageBackground as EImageBackground } from "expo-image"; -import { LinearGradient, type LinearGradientProps } from "expo-linear-gradient"; import type { ComponentProps, ReactNode } from "react"; import type { ImageStyle } from "react-native"; import { Platform } from "react-native"; import { withUniwind } from "uniwind"; -import { useYoshiki } from "yoshiki/native"; import type { KImage } from "~/models"; import { useToken } from "~/providers/account-context"; import { cn } from "~/utils"; @@ -65,40 +63,3 @@ export const PosterBackground = ({ /> ); }; - -export const GradientImageBackground = ({ - gradient, - gradientStyle, - children, - ...props -}: ComponentProps & { - gradient?: Partial; - gradientStyle?: Parameters["css"]>[0]; -}) => { - const { css, theme } = useYoshiki(); - - return ( - - - {children} - - - ); -}; diff --git a/front/src/primitives/select.tsx b/front/src/primitives/select.tsx index a9ffbdfb..34d3f9a9 100644 --- a/front/src/primitives/select.tsx +++ b/front/src/primitives/select.tsx @@ -1,6 +1,5 @@ import ExpandMore from "@material-symbols/svg-400/rounded/keyboard_arrow_down-fill.svg"; import { Button } from "./button"; -import { Icon } from "./icons"; import { Menu } from "./menu"; export const Select = ({ @@ -16,11 +15,7 @@ export const Select = ({ getLabel: (key: Value) => string; }) => { return ( - } - > + {values.map((x) => ( )} @@ -273,7 +264,7 @@ const Description = ({ genres: Genre[]; studios: Studio[]; externalIds: Metadata; -} & Stylable) => { +}) => { const { t } = useTranslation(); return ( diff --git a/front/src/ui/home/header.tsx b/front/src/ui/home/header.tsx index 7931d90e..f5a0fd35 100644 --- a/front/src/ui/home/header.tsx +++ b/front/src/ui/home/header.tsx @@ -7,11 +7,11 @@ import { min, percent, px, rem, vh } from "yoshiki/native"; import { type KImage, Show } from "~/models"; import { ContrastArea, - GradientImageBackground, H1, H2, IconButton, IconFab, + ImageBackground, Link, P, Skeleton, @@ -19,6 +19,7 @@ import { ts, } from "~/primitives"; import type { QueryIdentifier } from "~/query"; +import { cn } from "~/utils"; export const Header = ({ name, @@ -27,6 +28,7 @@ export const Header = ({ tagline, link, infoLink, + className, ...props }: { name: string; @@ -35,86 +37,55 @@ export const Header = ({ tagline: string | null; link: string | null; infoLink: string; + className?: string; }) => { const { t } = useTranslation(); return ( - - {({ css }) => ( - - -

- {name} -

- - {link !== null && ( - - )} - - {tagline && ( -

- {tagline} -

- )} -
-

- {description} -

-
-
+ + {...props} + > + + +

+ {name} +

+ + {link !== null && ( + + )} + + {tagline && ( +

{tagline}

+ )} +
+

+ {description} +

+
+
); }; diff --git a/front/src/ui/home/recommended.tsx b/front/src/ui/home/recommended.tsx index c26bc2fb..32860ec4 100644 --- a/front/src/ui/home/recommended.tsx +++ b/front/src/ui/home/recommended.tsx @@ -35,7 +35,8 @@ export const ItemDetails = ({ href, playHref, watchStatus, - unseenEpisodesCount, + availableCount, + seenCount, ...props }: { slug: string; @@ -49,7 +50,8 @@ export const ItemDetails = ({ href: string; playHref: string | null; watchStatus: WatchStatusV | null; - unseenEpisodesCount: number | null; + availableCount?: number | null; + seenCount?: number | null; }) => { const [moreOpened, setMoreOpened] = useState(false); const { css } = useYoshiki("recommended-card"); @@ -120,7 +122,8 @@ export const ItemDetails = ({ { description={entry.name} thumbnail={entry.thumbnail ?? item.thumbnail} href={entry.href ?? "#"} - watchedPercent={entry.watchStatus?.percent || null} + watchedPercent={entry.progress.percent} /> ); } diff --git a/front/src/ui/settings/account.tsx b/front/src/ui/settings/account.tsx index ddbd5161..121ce376 100644 --- a/front/src/ui/settings/account.tsx +++ b/front/src/ui/settings/account.tsx @@ -237,7 +237,6 @@ const ChangePopup = ({ setValue(v)} /> @@ -299,7 +298,6 @@ const ChangePasswordPopup = ({ {hasPassword && ( setOldValue(v)} placeholder={t("settings.account.password.oldPassword")} @@ -307,7 +305,6 @@ const ChangePasswordPopup = ({ )} setNewValue(v)} placeholder={t("settings.account.password.newPassword")}