diff --git a/front/src/models/video.ts b/front/src/models/video.ts index b1370907..90eb4da0 100644 --- a/front/src/models/video.ts +++ b/front/src/models/video.ts @@ -1,4 +1,46 @@ import { z } from "zod/v4"; +import { Entry } from "./entry"; +import { Extra } from "./extra"; +import { zdate } from "./utils/utils"; + +export const Video = z.object({ + id: z.string(), + path: z.string(), + rendering: z.string(), + part: z.int().min(0).nullable(), + version: z.int().min(0).default(1), + guess: z.object({ + title: z.string(), + kind: z.enum(["episode", "movie", "extra"]).nullable().optional(), + extraKind: Extra.shape.kind.optional().nullable(), + years: z.array(z.int()).default([]), + episodes: z + .array( + z.object({ + season: z.int().nullable(), + episode: z.int(), + }), + ) + .default([]), + externalId: z.record(z.string(), z.string()).default({}), + + // Name of the tool that made the guess + from: z.string(), + get history() { + return z.array(Video.shape.guess.omit({ history: true })).default([]); + }, + }), + createdAt: zdate(), + updatedAt: zdate(), +}); + +export const FullVideo = Video.extend({ + slugs: z.array(z.string()), + entries: z.array(Entry), + previous: z.object({ video: z.string(), entry: Entry }).nullable().optional(), + next: z.object({ video: z.string(), entry: Entry }).nullable().optional(), +}); +export type FullVideo = z.infer; export const EmbeddedVideo = z.object({ id: z.string(), diff --git a/front/src/ui/player/index.tsx b/front/src/ui/player/index.tsx index 88cc25c0..e1a71687 100644 --- a/front/src/ui/player/index.tsx +++ b/front/src/ui/player/index.tsx @@ -3,15 +3,9 @@ import { type ComponentProps, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Platform, StyleSheet, View } from "react-native"; import { useYoshiki } from "yoshiki/native"; -import { - Episode, - Movie, - type QueryIdentifier, - useFetch, - type WatchInfo, - WatchInfoP, -} from "~/models"; +import { type Episode, FullVideo, type Movie, VideoInfo } from "~/models"; import { Head } from "~/primitives"; +import type { QueryIdentifier } from "~/query"; import { Back, Hover, LoadingIndicator } from "./components/hover"; import { useVideoKeyboard } from "./keyboard"; import { durationAtom, fullscreenAtom, Video } from "./state"; @@ -181,30 +175,15 @@ export const Player = ({ ); }; -Player.query = ( - type: "episode" | "movie", - slug: string, -): QueryIdentifier => - type === "episode" - ? { - path: ["episode", slug], - params: { - fields: ["nextEpisode", "previousEpisode", "show", "watchStatus"], - }, - parser: EpisodeP.transform((x) => ({ ...x, type: "episode" })), - } - : { - path: ["movie", slug], - params: { - fields: ["watchStatus"], - }, - parser: MovieP.transform((x) => ({ ...x, type: "movie" })), - }; - -Player.infoQuery = ( - type: "episode" | "movie", - slug: string, -): QueryIdentifier => ({ - path: [type, slug, "info"], - parser: WatchInfoP, +Player.query = (slug: string): QueryIdentifier => ({ + path: ["api", "videos", slug], + params: { + fields: ["next", "previous", "serie"], + }, + parser: FullVideo, +}); + +Player.infoQuery = (slug: string): QueryIdentifier => ({ + path: ["api", "videos", slug, "info"], + parser: VideoInfo, });