mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-05-23 15:42:28 -04:00
Clean up kind handling in the front
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
import { ReactNode, createContext, useContext, useEffect, useMemo, useRef } from "react";
|
||||
import { UserP } from "./resources";
|
||||
import { User, UserP } from "./resources";
|
||||
import { z } from "zod";
|
||||
import { zdate } from "./utils";
|
||||
import { removeAccounts, setAccountCookie, updateAccount } from "./account-internal";
|
||||
@@ -38,13 +38,13 @@ export const TokenP = z.object({
|
||||
});
|
||||
export type Token = z.infer<typeof TokenP>;
|
||||
|
||||
export const AccountP = UserP.and(
|
||||
z.object({
|
||||
token: TokenP,
|
||||
apiUrl: z.string(),
|
||||
selected: z.boolean(),
|
||||
}),
|
||||
);
|
||||
export const AccountP = UserP.merge(z.object({
|
||||
// set it optional for accounts logged in before the kind was present
|
||||
kind: z.literal("user").optional(),
|
||||
token: TokenP,
|
||||
apiUrl: z.string(),
|
||||
selected: z.boolean(),
|
||||
}));
|
||||
export type Account = z.infer<typeof AccountP>;
|
||||
|
||||
const AccountContext = createContext<(Account & { select: () => void; remove: () => void })[]>([]);
|
||||
@@ -100,7 +100,7 @@ export const AccountProvider = ({
|
||||
const user = useFetch({
|
||||
path: ["auth", "me"],
|
||||
parser: UserP,
|
||||
placeholderData: selected,
|
||||
placeholderData: selected as User,
|
||||
enabled: !!selected,
|
||||
timeout: 5_000,
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { z } from "zod";
|
||||
import { withImages, ResourceP } from "../traits";
|
||||
|
||||
export const CollectionP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("collection").extend({
|
||||
/**
|
||||
* The title of this collection.
|
||||
*/
|
||||
@@ -31,8 +31,7 @@ export const CollectionP = withImages(
|
||||
* The summary of this show.
|
||||
*/
|
||||
overview: z.string().nullable(),
|
||||
}),
|
||||
"collections",
|
||||
})
|
||||
).transform((x) => ({
|
||||
...x,
|
||||
href: `/collection/${x.slug}`,
|
||||
|
||||
@@ -24,7 +24,7 @@ import { withImages, imageFn } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const BaseEpisodeP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("episode").extend({
|
||||
/**
|
||||
* The season in witch this episode is in.
|
||||
*/
|
||||
@@ -72,7 +72,6 @@ export const BaseEpisodeP = withImages(
|
||||
*/
|
||||
showId: z.string(),
|
||||
}),
|
||||
"episodes",
|
||||
)
|
||||
.transform((x) => ({
|
||||
...x,
|
||||
|
||||
@@ -23,28 +23,19 @@ import { CollectionP } from "./collection";
|
||||
import { MovieP } from "./movie";
|
||||
import { ShowP } from "./show";
|
||||
|
||||
/**
|
||||
* The type of item, ether a show, a movie or a collection.
|
||||
*/
|
||||
export enum ItemKind {
|
||||
Show = "Show",
|
||||
Movie = "Movie",
|
||||
Collection = "Collection",
|
||||
}
|
||||
|
||||
export const LibraryItemP = z.union([
|
||||
/*
|
||||
* Either a Show
|
||||
*/
|
||||
ShowP.and(z.object({ kind: z.literal(ItemKind.Show) })),
|
||||
ShowP,
|
||||
/*
|
||||
* Or a Movie
|
||||
*/
|
||||
MovieP.and(z.object({ kind: z.literal(ItemKind.Movie) })),
|
||||
MovieP,
|
||||
/*
|
||||
* Or a Collection
|
||||
*/
|
||||
CollectionP.and(z.object({ kind: z.literal(ItemKind.Collection) })),
|
||||
CollectionP,
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ import { MetadataP } from "./metadata";
|
||||
import { WatchStatusP } from "./watch-status";
|
||||
|
||||
export const MovieP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("movie").extend({
|
||||
/**
|
||||
* The title of this movie.
|
||||
*/
|
||||
@@ -105,7 +105,6 @@ export const MovieP = withImages(
|
||||
*/
|
||||
watchStatus: WatchStatusP.optional().nullable(),
|
||||
}),
|
||||
"movies",
|
||||
)
|
||||
.transform((x) => ({
|
||||
...x,
|
||||
|
||||
@@ -22,23 +22,15 @@ import { z } from "zod";
|
||||
import { MovieP } from "./movie";
|
||||
import { EpisodeP } from "./episode";
|
||||
|
||||
/**
|
||||
* The type of item, ether a a movie or an episode.
|
||||
*/
|
||||
export enum NewsKind {
|
||||
Episode = "Episode",
|
||||
Movie = "Movie",
|
||||
}
|
||||
|
||||
export const NewsP = z.union([
|
||||
/*
|
||||
* Either an episode
|
||||
*/
|
||||
EpisodeP.and(z.object({ kind: z.literal(NewsKind.Episode) })),
|
||||
EpisodeP,
|
||||
/*
|
||||
* Or a Movie
|
||||
*/
|
||||
MovieP.and(z.object({ kind: z.literal(NewsKind.Movie) })),
|
||||
MovieP,
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ import { withImages } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const PersonP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("people").extend({
|
||||
/**
|
||||
* The name of this person.
|
||||
*/
|
||||
@@ -40,7 +40,6 @@ export const PersonP = withImages(
|
||||
*/
|
||||
role: z.string().optional(),
|
||||
}),
|
||||
"people",
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ import { withImages } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const SeasonP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("season").extend({
|
||||
/**
|
||||
* The name of this season.
|
||||
*/
|
||||
@@ -50,7 +50,6 @@ export const SeasonP = withImages(
|
||||
*/
|
||||
episodesCount: z.number(),
|
||||
}),
|
||||
"seasons",
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,10 +22,8 @@ import { z } from "zod";
|
||||
import { zdate } from "../utils";
|
||||
import { withImages, ResourceP } from "../traits";
|
||||
import { Genre } from "./genre";
|
||||
import { SeasonP } from "./season";
|
||||
import { StudioP } from "./studio";
|
||||
import { BaseEpisodeP } from "./episode.base";
|
||||
import { CollectionP } from "./collection";
|
||||
import { MetadataP } from "./metadata";
|
||||
import { ShowWatchStatusP } from "./watch-status";
|
||||
|
||||
@@ -40,7 +38,7 @@ export enum Status {
|
||||
}
|
||||
|
||||
export const ShowP = withImages(
|
||||
ResourceP.extend({
|
||||
ResourceP("show").extend({
|
||||
/**
|
||||
* The title of this show.
|
||||
*/
|
||||
@@ -106,7 +104,6 @@ export const ShowP = withImages(
|
||||
*/
|
||||
episodesCount: z.number().int().gte(0).optional(),
|
||||
}),
|
||||
"shows",
|
||||
)
|
||||
.transform((x) => {
|
||||
if (!x.thumbnail && x.poster) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
import { z } from "zod";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const StudioP = ResourceP.extend({
|
||||
export const StudioP = ResourceP("studio").extend({
|
||||
/**
|
||||
* The name of this studio.
|
||||
*/
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
import { z } from "zod";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
/**
|
||||
* The library that will contain Shows, Collections...
|
||||
*/
|
||||
export const UserP = ResourceP.extend({
|
||||
export const UserP = ResourceP("user").extend({
|
||||
/**
|
||||
* The name of this user.
|
||||
*/
|
||||
|
||||
@@ -22,23 +22,15 @@ import { z } from "zod";
|
||||
import { MovieP } from "./movie";
|
||||
import { ShowP } from "./show";
|
||||
|
||||
/**
|
||||
* The type of item, ether a show, a movie or an episode.
|
||||
*/
|
||||
export enum WatchlistKind {
|
||||
Show = "Show",
|
||||
Movie = "Movie",
|
||||
}
|
||||
|
||||
export const WatchlistP = z.union([
|
||||
/*
|
||||
* Either a show
|
||||
*/
|
||||
ShowP.and(z.object({ kind: z.literal(WatchlistKind.Show) })),
|
||||
ShowP,
|
||||
/*
|
||||
* Or a Movie
|
||||
*/
|
||||
MovieP.and(z.object({ kind: z.literal(WatchlistKind.Movie) })),
|
||||
MovieP,
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,13 +62,13 @@ const addQualities = (x: object | null | undefined, href: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const withImages = <T extends ZodRawShape>(parser: ZodObject<T>, type: string) => {
|
||||
export const withImages = <T extends ZodRawShape>(parser: ZodObject<T>) => {
|
||||
return parser.merge(ImagesP).transform((x) => {
|
||||
return {
|
||||
...x,
|
||||
poster: addQualities(x.poster, `/${type}/${x.slug}/poster`),
|
||||
thumbnail: addQualities(x.thumbnail, `/${type}/${x.slug}/thumbnail`),
|
||||
logo: addQualities(x.logo, `/${type}/${x.slug}/logo`),
|
||||
poster: addQualities(x.poster, `/${x.kind}/${x.slug}/poster`),
|
||||
thumbnail: addQualities(x.thumbnail, `/${x.kind}/${x.slug}/thumbnail`),
|
||||
logo: addQualities(x.logo, `/${x.kind}/${x.slug}/logo`),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@@ -20,20 +20,26 @@
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
export const ResourceP = z.object({
|
||||
/**
|
||||
* A unique ID for this type of resource. This can't be changed and duplicates are not allowed.
|
||||
*/
|
||||
id: z.string(),
|
||||
export const ResourceP = <T extends string>(kind: T) =>
|
||||
z.object({
|
||||
/**
|
||||
* A unique ID for this type of resource. This can't be changed and duplicates are not allowed.
|
||||
*/
|
||||
id: z.string(),
|
||||
|
||||
/**
|
||||
* A human-readable identifier that can be used instead of an ID. A slug must be unique for a type
|
||||
* of resource but it can be changed.
|
||||
*/
|
||||
slug: z.string(),
|
||||
});
|
||||
/**
|
||||
* A human-readable identifier that can be used instead of an ID. A slug must be unique for a type
|
||||
* of resource but it can be changed.
|
||||
*/
|
||||
slug: z.string(),
|
||||
|
||||
/**
|
||||
* The type of resource
|
||||
*/
|
||||
kind: z.literal(kind),
|
||||
});
|
||||
|
||||
/**
|
||||
* The base trait used to represent identifiable resources.
|
||||
*/
|
||||
export type Resource = z.infer<typeof ResourceP>;
|
||||
export type Resource = z.infer<ReturnType<typeof ResourceP>>;
|
||||
|
||||
Reference in New Issue
Block a user