mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Parse new fields in the front
This commit is contained in:
parent
5489f601d2
commit
f872deffb8
75
front/packages/models/src/resources/episode.base.ts
Normal file
75
front/packages/models/src/resources/episode.base.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Kyoo - A portable and vast media library solution.
|
||||||
|
* Copyright (c) Kyoo.
|
||||||
|
*
|
||||||
|
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
*
|
||||||
|
* Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* Kyoo is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { z } from "zod";
|
||||||
|
import { zdate } from "../utils";
|
||||||
|
import { withImages, imageFn } from "../traits";
|
||||||
|
import { ResourceP } from "../traits/resource";
|
||||||
|
|
||||||
|
export const BaseEpisodeP = withImages(
|
||||||
|
ResourceP.extend({
|
||||||
|
/**
|
||||||
|
* The season in witch this episode is in.
|
||||||
|
*/
|
||||||
|
seasonNumber: z.number().nullable(),
|
||||||
|
/**
|
||||||
|
* The number of this episode in it's season.
|
||||||
|
*/
|
||||||
|
episodeNumber: z.number().nullable(),
|
||||||
|
/**
|
||||||
|
* The absolute number of this episode. It's an episode number that is not reset to 1 after a new
|
||||||
|
* season.
|
||||||
|
*/
|
||||||
|
absoluteNumber: z.number().nullable(),
|
||||||
|
/**
|
||||||
|
* The title of this episode.
|
||||||
|
*/
|
||||||
|
name: z.string().nullable(),
|
||||||
|
/**
|
||||||
|
* The overview of this episode.
|
||||||
|
*/
|
||||||
|
overview: z.string().nullable(),
|
||||||
|
/**
|
||||||
|
* How long is this movie? (in minutes).
|
||||||
|
*/
|
||||||
|
runtime: z.number().int(),
|
||||||
|
/**
|
||||||
|
* The release date of this episode. It can be null if unknown.
|
||||||
|
*/
|
||||||
|
releaseDate: zdate().nullable(),
|
||||||
|
/**
|
||||||
|
* The links to see a movie or an episode.
|
||||||
|
*/
|
||||||
|
links: z.object({
|
||||||
|
/**
|
||||||
|
* The direct link to the unprocessed video (pristine quality).
|
||||||
|
*/
|
||||||
|
direct: z.string().transform(imageFn),
|
||||||
|
/**
|
||||||
|
* The link to an HLS master playlist containing all qualities available for this video.
|
||||||
|
*/
|
||||||
|
hls: z.string().transform(imageFn),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
"episodes",
|
||||||
|
).transform((x) => ({
|
||||||
|
...x,
|
||||||
|
href: `/watch/${x.slug}`,
|
||||||
|
}));
|
@ -19,64 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zdate } from "../utils";
|
|
||||||
import { withImages, imageFn } from "../traits";
|
|
||||||
import { ResourceP } from "../traits/resource";
|
|
||||||
import { ShowP } from "./show";
|
import { ShowP } from "./show";
|
||||||
|
import { BaseEpisodeP } from "./episode.base";
|
||||||
export const BaseEpisodeP = withImages(
|
|
||||||
ResourceP.extend({
|
|
||||||
/**
|
|
||||||
* The season in witch this episode is in.
|
|
||||||
*/
|
|
||||||
seasonNumber: z.number().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of this episode in it's season.
|
|
||||||
*/
|
|
||||||
episodeNumber: z.number().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The absolute number of this episode. It's an episode number that is not reset to 1 after a new
|
|
||||||
* season.
|
|
||||||
*/
|
|
||||||
absoluteNumber: z.number().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The title of this episode.
|
|
||||||
*/
|
|
||||||
name: z.string().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The overview of this episode.
|
|
||||||
*/
|
|
||||||
overview: z.string().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The release date of this episode. It can be null if unknown.
|
|
||||||
*/
|
|
||||||
releaseDate: zdate().nullable(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The links to see a movie or an episode.
|
|
||||||
*/
|
|
||||||
links: z.object({
|
|
||||||
/**
|
|
||||||
* The direct link to the unprocessed video (pristine quality).
|
|
||||||
*/
|
|
||||||
direct: z.string().transform(imageFn),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The link to an HLS master playlist containing all qualities available for this video.
|
|
||||||
*/
|
|
||||||
hls: z.string().transform(imageFn),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
"episodes",
|
|
||||||
).transform((x) => ({
|
|
||||||
...x,
|
|
||||||
href: `/watch/${x.slug}`,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const EpisodeP = BaseEpisodeP.and(
|
export const EpisodeP = BaseEpisodeP.and(
|
||||||
z.object({
|
z.object({
|
||||||
|
@ -51,6 +51,14 @@ export const MovieP = withImages(
|
|||||||
* /** Is this movie not aired yet or finished?
|
* /** Is this movie not aired yet or finished?
|
||||||
*/
|
*/
|
||||||
status: z.nativeEnum(Status),
|
status: z.nativeEnum(Status),
|
||||||
|
/**
|
||||||
|
* How well this item is rated? (from 0 to 100).
|
||||||
|
*/
|
||||||
|
rating: z.number().int().gte(0).lte(100),
|
||||||
|
/**
|
||||||
|
* How long is this movie? (in minutes).
|
||||||
|
*/
|
||||||
|
runtime: z.number().int(),
|
||||||
/**
|
/**
|
||||||
* The date this movie aired. It can also be null if this is unknown.
|
* The date this movie aired. It can also be null if this is unknown.
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { MovieP } from "./movie";
|
import { MovieP } from "./movie";
|
||||||
import { BaseEpisodeP } from "./episode";
|
import { BaseEpisodeP } from "./episode.base";
|
||||||
import { ResourceP } from "../traits/resource";
|
import { ResourceP } from "../traits/resource";
|
||||||
import { withImages } from "../traits/images";
|
import { withImages } from "../traits/images";
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import { withImages, ResourceP } from "../traits";
|
|||||||
import { Genre } from "./genre";
|
import { Genre } from "./genre";
|
||||||
import { SeasonP } from "./season";
|
import { SeasonP } from "./season";
|
||||||
import { StudioP } from "./studio";
|
import { StudioP } from "./studio";
|
||||||
|
import { BaseEpisodeP } from "./episode.base";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The enum containing show's status.
|
* The enum containing show's status.
|
||||||
@ -61,6 +62,10 @@ export const ShowP = withImages(
|
|||||||
* Is this show airing, not aired yet or finished?
|
* Is this show airing, not aired yet or finished?
|
||||||
*/
|
*/
|
||||||
status: z.nativeEnum(Status),
|
status: z.nativeEnum(Status),
|
||||||
|
/**
|
||||||
|
* How well this item is rated? (from 0 to 100).
|
||||||
|
*/
|
||||||
|
rating: z.number().int().gte(0).lte(100),
|
||||||
/**
|
/**
|
||||||
* The date this show started airing. It can be null if this is unknown.
|
* The date this show started airing. It can be null if this is unknown.
|
||||||
*/
|
*/
|
||||||
@ -85,6 +90,10 @@ export const ShowP = withImages(
|
|||||||
* The list of seasons of this show.
|
* The list of seasons of this show.
|
||||||
*/
|
*/
|
||||||
seasons: z.array(SeasonP).optional(),
|
seasons: z.array(SeasonP).optional(),
|
||||||
|
/**
|
||||||
|
* The first episode of this show
|
||||||
|
*/
|
||||||
|
firstEpisode: BaseEpisodeP.optional().nullable(),
|
||||||
}),
|
}),
|
||||||
"shows",
|
"shows",
|
||||||
)
|
)
|
||||||
@ -100,7 +109,7 @@ export const ShowP = withImages(
|
|||||||
})
|
})
|
||||||
.transform((x) => ({
|
.transform((x) => ({
|
||||||
href: `/show/${x.slug}`,
|
href: `/show/${x.slug}`,
|
||||||
playHref: `/watch/${x.slug}-s1e1`,
|
playHref: x.firstEpisode ? `/watch/${x.firstEpisode.slug}` : null,
|
||||||
...x,
|
...x,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ const TitleLine = ({
|
|||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
playHref?: string;
|
playHref?: string | null;
|
||||||
name?: string;
|
name?: string;
|
||||||
tagline?: string | null;
|
tagline?: string | null;
|
||||||
date?: string | null;
|
date?: string | null;
|
||||||
@ -192,6 +192,7 @@ const TitleLine = ({
|
|||||||
</Skeleton>
|
</Skeleton>
|
||||||
)}
|
)}
|
||||||
<View {...css({ flexDirection: "row" })}>
|
<View {...css({ flexDirection: "row" })}>
|
||||||
|
{playHref !== null && (
|
||||||
<IconFab
|
<IconFab
|
||||||
icon={PlayArrow}
|
icon={PlayArrow}
|
||||||
as={Link}
|
as={Link}
|
||||||
@ -203,6 +204,7 @@ const TitleLine = ({
|
|||||||
})}
|
})}
|
||||||
{...tooltip(t("show.play"))}
|
{...tooltip(t("show.play"))}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
{trailerUrl && (
|
{trailerUrl && (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={Theaters}
|
icon={Theaters}
|
||||||
|
@ -85,7 +85,7 @@ const query = (slug: string): QueryIdentifier<Show> => ({
|
|||||||
parser: ShowP,
|
parser: ShowP,
|
||||||
path: ["shows", slug],
|
path: ["shows", slug],
|
||||||
params: {
|
params: {
|
||||||
fields: ["studio"],
|
fields: ["studio", "firstEpisode"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export const Header = ({
|
|||||||
thumbnail: KyooImage | null;
|
thumbnail: KyooImage | null;
|
||||||
overview: string | null;
|
overview: string | null;
|
||||||
tagline: string | null;
|
tagline: string | null;
|
||||||
link: string;
|
link: string | null;
|
||||||
infoLink: string;
|
infoLink: string;
|
||||||
}>) => {
|
}>) => {
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
@ -70,6 +70,7 @@ export const Header = ({
|
|||||||
>
|
>
|
||||||
<H1>{name}</H1>
|
<H1>{name}</H1>
|
||||||
<View {...css({ flexDirection: "row" })}>
|
<View {...css({ flexDirection: "row" })}>
|
||||||
|
{link !== null && (
|
||||||
<IconFab
|
<IconFab
|
||||||
icon={PlayArrow}
|
icon={PlayArrow}
|
||||||
aria-label={t("show.play")}
|
aria-label={t("show.play")}
|
||||||
@ -78,6 +79,7 @@ export const Header = ({
|
|||||||
{...tooltip(t("show.play"))}
|
{...tooltip(t("show.play"))}
|
||||||
{...css({ marginRight: ts(1) })}
|
{...css({ marginRight: ts(1) })}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={Info}
|
icon={Info}
|
||||||
aria-label={t("home.info")}
|
aria-label={t("home.info")}
|
||||||
@ -96,4 +98,7 @@ export const Header = ({
|
|||||||
Header.query = (): QueryIdentifier<LibraryItem> => ({
|
Header.query = (): QueryIdentifier<LibraryItem> => ({
|
||||||
parser: LibraryItemP,
|
parser: LibraryItemP,
|
||||||
path: ["items", "random"],
|
path: ["items", "random"],
|
||||||
|
params: {
|
||||||
|
fields: "firstEpisode",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -66,7 +66,7 @@ export const ItemDetails = ({
|
|||||||
genres: Genre[] | null;
|
genres: Genre[] | null;
|
||||||
overview: string | null;
|
overview: string | null;
|
||||||
href: string;
|
href: string;
|
||||||
playHref: string;
|
playHref: string | null;
|
||||||
}>) => {
|
}>) => {
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
const { css } = useYoshiki("recommanded-card");
|
const { css } = useYoshiki("recommanded-card");
|
||||||
@ -136,6 +136,7 @@ export const ItemDetails = ({
|
|||||||
<ScrollView horizontal>
|
<ScrollView horizontal>
|
||||||
{genres?.map((x) => <Chip key={x} label={x} {...css({ mX: ts(0.5) })} />)}
|
{genres?.map((x) => <Chip key={x} label={x} {...css({ mX: ts(0.5) })} />)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
{playHref !== null && (
|
||||||
<IconFab
|
<IconFab
|
||||||
icon={PlayArrow}
|
icon={PlayArrow}
|
||||||
size={20}
|
size={20}
|
||||||
@ -143,6 +144,7 @@ export const ItemDetails = ({
|
|||||||
onPress={() => push(playHref ?? "")}
|
onPress={() => push(playHref ?? "")}
|
||||||
{...css({ fover: { self: { transform: "scale(1.2)" as any, mX: ts(0.5) } } })}
|
{...css({ fover: { self: { transform: "scale(1.2)" as any, mX: ts(0.5) } } })}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Link>
|
</Link>
|
||||||
@ -197,5 +199,6 @@ Recommanded.query = (): QueryIdentifier<LibraryItem> => ({
|
|||||||
params: {
|
params: {
|
||||||
sortBy: "random",
|
sortBy: "random",
|
||||||
limit: 6,
|
limit: 6,
|
||||||
|
fields: "firstEpisode",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user