Fix some typescript issues

This commit is contained in:
Zoe Roux 2025-09-22 22:27:15 +02:00
parent 0ea10c4024
commit 69673d92f0
No known key found for this signature in database
9 changed files with 127 additions and 130 deletions

View File

@ -1,5 +1,5 @@
{ {
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json", "$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"formatter": { "formatter": {
"enabled": true, "enabled": true,
"formatWithErrors": true, "formatWithErrors": true,

View File

@ -1,6 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Platform, View } from "react-native"; import { View } from "react-native";
import { import {
percent, percent,
rem, rem,
@ -8,14 +8,11 @@ import {
type Theme, type Theme,
useYoshiki, useYoshiki,
} from "yoshiki/native"; } from "yoshiki/native";
import { EntryContext } from "~/components/items/context-menus"; import type { KImage } from "~/models";
import { ItemProgress } from "~/components/items/item-grid";
import type { KImage, WatchStatusV } from "~/models";
import { import {
focusReset, focusReset,
Image, Image,
ImageBackground, ImageBackground,
important,
Link, Link,
P, P,
Skeleton, Skeleton,
@ -31,7 +28,7 @@ export const EntryBox = ({
thumbnail, thumbnail,
href, href,
watchedPercent, watchedPercent,
watchedStatus, // watchedStatus,
...props ...props
}: Stylable & { }: Stylable & {
slug: string; slug: string;
@ -42,7 +39,7 @@ export const EntryBox = ({
href: string; href: string;
thumbnail: KImage | null; thumbnail: KImage | null;
watchedPercent: number | null; watchedPercent: number | null;
watchedStatus: WatchStatusV | null; // watchedStatus: WatchStatusV | null;
}) => { }) => {
const [moreOpened, setMoreOpened] = useState(false); const [moreOpened, setMoreOpened] = useState(false);
const { css } = useYoshiki("episodebox"); const { css } = useYoshiki("episodebox");
@ -89,27 +86,27 @@ export const EntryBox = ({
layout={{ width: percent(100), aspectRatio: 16 / 9 }} layout={{ width: percent(100), aspectRatio: 16 / 9 }}
{...(css("poster") as any)} {...(css("poster") as any)}
> >
{(watchedPercent || watchedStatus === "completed") && ( {/* {(watchedPercent || watchedStatus === "completed") && ( */}
<ItemProgress watchPercent={watchedPercent ?? 100} /> {/* <ItemProgress watchPercent={watchedPercent ?? 100} /> */}
)} {/* )} */}
<EntryContext {/* <EntryContext */}
slug={slug} {/* slug={slug} */}
serieSlug={serieSlug} {/* serieSlug={serieSlug} */}
status={watchedStatus} {/* status={watchedStatus} */}
isOpen={moreOpened} {/* isOpen={moreOpened} */}
setOpen={(v) => setMoreOpened(v)} {/* setOpen={(v) => setMoreOpened(v)} */}
{...css([ {/* {...css([ */}
{ {/* { */}
position: "absolute", {/* position: "absolute", */}
top: 0, {/* top: 0, */}
right: 0, {/* right: 0, */}
bg: (theme) => theme.darkOverlay, {/* bg: (theme) => theme.darkOverlay, */}
}, {/* }, */}
"more", {/* "more", */}
Platform.OS === "web" && {/* Platform.OS === "web" && */}
moreOpened && { display: important("flex") }, {/* moreOpened && { display: important("flex") }, */}
])} {/* ])} */}
/> {/* /> */}
</ImageBackground> </ImageBackground>
<P {...css([{ marginY: 0, textAlign: "center" }, "title"])}> <P {...css([{ marginY: 0, textAlign: "center" }, "title"])}>
{name ?? t("show.episodeNoMetadata")} {name ?? t("show.episodeNoMetadata")}

View File

@ -12,7 +12,7 @@ import { HR, IconButton, Menu, tooltip } from "~/primitives";
import { useAccount } from "~/providers/account-context"; import { useAccount } from "~/providers/account-context";
import { useMutation } from "~/query"; import { useMutation } from "~/query";
import { watchListIcon } from "./watchlist-info"; import { watchListIcon } from "./watchlist-info";
// import { useDownloader } from "../../packages/ui/src/downloadses/ui/src/downloads"; // import { useDownloader } from "../../packages/ui/src/downloads/ui/src/downloads";
export const EntryContext = ({ export const EntryContext = ({
slug, slug,
@ -27,32 +27,30 @@ export const EntryContext = ({
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<> <Menu
<Menu Trigger={IconButton}
Trigger={IconButton} icon={MoreVert}
icon={MoreVert} {...tooltip(t("misc.more"))}
{...tooltip(t("misc.more"))} {...(css([Platform.OS !== "web" && { display: "none" }], props) as any)}
{...(css([Platform.OS !== "web" && { display: "none" }], props) as any)} >
> {serieSlug && (
{serieSlug && (
<Menu.Item
label={t("home.episodeMore.goToShow")}
icon={Info}
href={`/series/${serieSlug}`}
/>
)}
{/* <Menu.Item */}
{/* label={t("home.episodeMore.download")} */}
{/* icon={Download} */}
{/* onSelect={() => downloader(type, slug)} */}
{/* /> */}
<Menu.Item <Menu.Item
label={t("home.episodeMore.mediainfo")} label={t("home.episodeMore.goToShow")}
icon={MovieInfo} icon={Info}
href={`/entries/${slug}/info`} href={`/series/${serieSlug}`}
/> />
</Menu> )}
</> {/* <Menu.Item */}
{/* label={t("home.episodeMore.download")} */}
{/* icon={Download} */}
{/* onSelect={() => downloader(type, slug)} */}
{/* /> */}
<Menu.Item
label={t("home.episodeMore.mediainfo")}
icon={MovieInfo}
href={`/entries/${slug}/info`}
/>
</Menu>
); );
}; };
@ -87,60 +85,58 @@ export const ItemContext = ({
}); });
return ( return (
<> <Menu
<Menu Trigger={IconButton}
Trigger={IconButton} icon={MoreVert}
icon={MoreVert} {...tooltip(t("misc.more"))}
{...tooltip(t("misc.more"))} {...(css([Platform.OS !== "web" && { display: "none" }], props) as any)}
{...(css([Platform.OS !== "web" && { display: "none" }], props) as any)} >
<Menu.Sub
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")}
disabled={!account}
icon={watchListIcon(status)}
> >
<Menu.Sub {Object.values(WatchStatusV).map((x) => (
label={account ? t("show.watchlistEdit") : t("show.watchlistLogin")} <Menu.Item
disabled={!account} key={x}
icon={watchListIcon(status)} label={t(
> `show.watchlistMark.${x.toLowerCase() as Lowercase<WatchStatusV>}`,
{Object.values(WatchStatusV).map((x) => ( )}
<Menu.Item onSelect={() => mutation.mutate(x)}
key={x} selected={x === status}
label={t( />
`show.watchlistMark.${x.toLowerCase() as Lowercase<WatchStatusV>}`, ))}
)} {status !== null && (
onSelect={() => mutation.mutate(x)} <Menu.Item
selected={x === status} label={t("show.watchlistMark.null")}
/> onSelect={() => mutation.mutate(null)}
))} />
{status !== null && (
<Menu.Item
label={t("show.watchlistMark.null")}
onSelect={() => mutation.mutate(null)}
/>
)}
</Menu.Sub>
{kind === "movie" && (
<>
{/* <Menu.Item */}
{/* label={t("home.episodeMore.download")} */}
{/* icon={Download} */}
{/* onSelect={() => downloader(type, slug)} */}
{/* /> */}
<Menu.Item
label={t("home.episodeMore.mediainfo")}
icon={MovieInfo}
href={`/movies/${slug}/info`}
/>
</>
)} )}
{account?.isAdmin === true && ( </Menu.Sub>
<> {kind === "movie" && (
<HR /> <>
<Menu.Item {/* <Menu.Item */}
label={t("home.refreshMetadata")} {/* label={t("home.episodeMore.download")} */}
icon={Refresh} {/* icon={Download} */}
onSelect={() => metadataRefreshMutation.mutate()} {/* onSelect={() => downloader(type, slug)} */}
/> {/* /> */}
</> <Menu.Item
)} label={t("home.episodeMore.mediainfo")}
</Menu> icon={MovieInfo}
</> href={`/movies/${slug}/info`}
/>
</>
)}
{account?.isAdmin === true && (
<>
<HR />
<Menu.Item
label={t("home.refreshMetadata")}
icon={Refresh}
onSelect={() => metadataRefreshMutation.mutate()}
/>
</>
)}
</Menu>
); );
}; };

View File

@ -1,7 +1,7 @@
import Done from "@material-symbols/svg-400/rounded/check-fill.svg"; import Done from "@material-symbols/svg-400/rounded/check-fill.svg";
import { View } from "react-native"; import { View } from "react-native";
import { max, rem, useYoshiki } from "yoshiki/native"; import { max, rem, useYoshiki } from "yoshiki/native";
import { WatchStatusV } from "~/models"; import type { WatchStatusV } from "~/models";
import { Icon, P, ts } from "~/primitives"; import { Icon, P, ts } from "~/primitives";
export const ItemWatchStatus = ({ export const ItemWatchStatus = ({
@ -14,8 +14,7 @@ export const ItemWatchStatus = ({
}) => { }) => {
const { css } = useYoshiki(); const { css } = useYoshiki();
if (watchStatus !== WatchStatusV.Completed && !unseenEpisodesCount) if (watchStatus !== "completed" && !unseenEpisodesCount) return null;
return null;
return ( return (
<View <View
@ -36,7 +35,7 @@ export const ItemWatchStatus = ({
props, props,
)} )}
> >
{watchStatus === WatchStatusV.Completed ? ( {watchStatus === "completed" ? (
<Icon icon={Done} size={16} /> <Icon icon={Done} size={16} />
) : ( ) : (
<P <P

View File

@ -1,6 +1,9 @@
import { z } from "zod"; import { z } from "zod";
import { User } from "./user"; import { User } from "./user";
// TODO: actually parse the token
const TokenP = z.string();
export const AccountP = User.and( export const AccountP = User.and(
z.object({ z.object({
token: TokenP, token: TokenP,

View File

@ -4,7 +4,6 @@ import { Genre } from "./utils/genre";
import { KImage } from "./utils/images"; import { KImage } from "./utils/images";
import { Metadata } from "./utils/metadata"; import { Metadata } from "./utils/metadata";
import { zdate } from "./utils/utils"; import { zdate } from "./utils/utils";
import { EmbeddedVideo } from "./video-embed";
export const Movie = z export const Movie = z
.object({ .object({

View File

@ -1,4 +1,4 @@
import { forwardRef, type ReactNode, useState } from "react"; import { type ReactNode, type Ref, useState } from "react";
import { import {
TextInput, TextInput,
type TextInputProps, type TextInputProps,
@ -6,20 +6,22 @@ import {
type ViewStyle, type ViewStyle,
} from "react-native"; } from "react-native";
import { px, type Theme, useYoshiki } from "yoshiki/native"; import { px, type Theme, useYoshiki } from "yoshiki/native";
import type { YoshikiEnhanced } from "./image/base-image"; import type { YoshikiEnhanced } from "./image";
import { focusReset, ts } from "./utils"; import { focusReset, ts } from "./utils";
export const Input = forwardRef< export const Input = ({
TextInput, placeholderTextColor,
{ variant = "small",
variant?: "small" | "big"; right,
right?: ReactNode; containerStyle,
containerStyle?: YoshikiEnhanced<ViewStyle>;
} & TextInputProps
>(function Input(
{ placeholderTextColor, variant = "small", right, containerStyle, ...props },
ref, ref,
) { ...props
}: {
variant?: "small" | "big";
right?: ReactNode;
containerStyle?: YoshikiEnhanced<ViewStyle>;
ref?: Ref<TextInput>;
} & TextInputProps) => {
const [focused, setFocused] = useState(false); const [focused, setFocused] = useState(false);
const { css, theme } = useYoshiki(); const { css, theme } = useYoshiki();
@ -64,4 +66,4 @@ export const Input = forwardRef<
{right} {right}
</View> </View>
); );
}); };

View File

@ -69,10 +69,11 @@ export const VolumeSlider = ({ player, ...props }: { player: VideoPlayer }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [volume, setVolume] = useState(player.volume); const [volume, setVolume] = useState(player.volume);
useEvent(player, "onVolumeChange", setVolume); const [muted, setMuted] = useState(player.muted);
// TODO: listen to `player.muted` changes (currently hook does not exists useEvent(player, "onVolumeChange", (info) => {
// const [muted, setMuted] = useState(player.muted); setVolume(info.volume);
const muted = player.muted; setMuted(info.muted);
});
return ( return (
<View <View

View File

@ -62,7 +62,7 @@ export const TouchControls = ({
}} }}
onDoublePress={(e) => { onDoublePress={(e) => {
if (!isTouch) { if (!isTouch) {
player.toggleFullscreen(); // player.toggleFullscreen();
return; return;
} }