mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add images links on the front instead of the back
This commit is contained in:
parent
c9c1ac5126
commit
1373d0ce26
@ -54,12 +54,11 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<Collection>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.Collections
|
||||
.Where(_database.Like<Collection>(x => x.Name + " " + x.Slug, $"%{query}%"))
|
||||
.Take(20)
|
||||
).ToListAsync())
|
||||
.Select(SetBackingImageSelf).ToList();
|
||||
.Where(_database.Like<Collection>(x => x.Name + " " + x.Slug, $"%{query}%"))
|
||||
.Take(20)
|
||||
).ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -77,7 +77,7 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<Episode>> Search(string query)
|
||||
{
|
||||
List<Episode> ret = await Sort(
|
||||
return await Sort(
|
||||
_database.Episodes
|
||||
.Include(x => x.Show)
|
||||
.Where(x => x.EpisodeNumber != null || x.AbsoluteNumber != null)
|
||||
@ -85,12 +85,6 @@ namespace Kyoo.Core.Controllers
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync();
|
||||
foreach (Episode ep in ret)
|
||||
{
|
||||
ep.Show!.Episodes = null;
|
||||
SetBackingImage(ep);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -54,14 +54,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<LibraryItem>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.LibraryItems
|
||||
.Where(_database.Like<LibraryItem>(x => x.Name, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -278,28 +278,6 @@ namespace Kyoo.Core.Controllers
|
||||
return query;
|
||||
}
|
||||
|
||||
protected void SetBackingImage(T? obj)
|
||||
{
|
||||
if (obj is not IThumbnails thumbs)
|
||||
return;
|
||||
string type = obj is LibraryItem item
|
||||
? item.Kind.ToString().ToLowerInvariant()
|
||||
: typeof(T).Name.ToLowerInvariant();
|
||||
|
||||
if (thumbs.Poster != null)
|
||||
thumbs.Poster.Path = $"/{type}/{obj.Slug}/poster";
|
||||
if (thumbs.Thumbnail != null)
|
||||
thumbs.Thumbnail.Path = $"/{type}/{obj.Slug}/thumbnail";
|
||||
if (thumbs.Logo != null)
|
||||
thumbs.Logo.Path = $"/{type}/{obj.Slug}/logo";
|
||||
}
|
||||
|
||||
protected T SetBackingImageSelf(T obj)
|
||||
{
|
||||
SetBackingImage(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's ID and make the <see cref="Database"/> instance track it.
|
||||
/// </summary>
|
||||
@ -309,7 +287,6 @@ namespace Kyoo.Core.Controllers
|
||||
protected virtual async Task<T> GetWithTracking(int id)
|
||||
{
|
||||
T? ret = await Database.Set<T>().AsTracking().FirstOrDefaultAsync(x => x.Id == id);
|
||||
SetBackingImage(ret);
|
||||
if (ret == null)
|
||||
throw new ItemNotFoundException($"No {typeof(T).Name} found with the id {id}");
|
||||
return ret;
|
||||
@ -346,8 +323,7 @@ namespace Kyoo.Core.Controllers
|
||||
public virtual Task<T?> GetOrDefault(int id, Include<T>? include = default)
|
||||
{
|
||||
return AddIncludes(Database.Set<T>(), include)
|
||||
.FirstOrDefaultAsync(x => x.Id == id)
|
||||
.Then(SetBackingImage);
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -357,12 +333,10 @@ namespace Kyoo.Core.Controllers
|
||||
{
|
||||
return AddIncludes(Database.Set<T>(), include)
|
||||
.OrderBy(x => EF.Functions.Random())
|
||||
.FirstOrDefaultAsync()
|
||||
.Then(SetBackingImage);
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
return AddIncludes(Database.Set<T>(), include)
|
||||
.FirstOrDefaultAsync(x => x.Slug == slug)
|
||||
.Then(SetBackingImage);
|
||||
.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -374,21 +348,19 @@ namespace Kyoo.Core.Controllers
|
||||
AddIncludes(Database.Set<T>(), include),
|
||||
sortBy
|
||||
)
|
||||
.FirstOrDefaultAsync(where)
|
||||
.Then(SetBackingImage);
|
||||
.FirstOrDefaultAsync(where);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract Task<ICollection<T>> Search(string query);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<ICollection<T>> GetAll(Expression<Func<T, bool>>? where = null,
|
||||
public virtual Task<ICollection<T>> GetAll(Expression<Func<T, bool>>? where = null,
|
||||
Sort<T>? sort = default,
|
||||
Pagination? limit = default,
|
||||
Include<T>? include = default)
|
||||
{
|
||||
return (await ApplyFilters(Database.Set<T>(), where, sort, limit, include))
|
||||
.Select(SetBackingImageSelf).ToList();
|
||||
return ApplyFilters(Database.Set<T>(), where, sort, limit, include);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -447,7 +419,6 @@ namespace Kyoo.Core.Controllers
|
||||
if (thumbs.Logo != null)
|
||||
Database.Entry(thumbs).Reference(x => x.Logo).TargetEntry!.State = EntityState.Added;
|
||||
}
|
||||
SetBackingImage(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -499,7 +470,6 @@ namespace Kyoo.Core.Controllers
|
||||
await EditRelations(old, edited);
|
||||
await Database.SaveChangesAsync();
|
||||
OnEdited?.Invoke(old);
|
||||
SetBackingImage(old);
|
||||
return old;
|
||||
}
|
||||
finally
|
||||
@ -523,7 +493,6 @@ namespace Kyoo.Core.Controllers
|
||||
|
||||
await Database.SaveChangesAsync();
|
||||
OnEdited?.Invoke(resource);
|
||||
SetBackingImage(resource);
|
||||
return resource;
|
||||
}
|
||||
finally
|
||||
|
@ -71,14 +71,12 @@ namespace Kyoo.Core.Controllers
|
||||
public override async Task<ICollection<Movie>> Search(string query)
|
||||
{
|
||||
query = $"%{query}%";
|
||||
return (await Sort(
|
||||
_database.Movies
|
||||
return await Sort(
|
||||
_database.Movies
|
||||
.Where(_database.Like<Movie>(x => x.Name + " " + x.Slug, query))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -65,14 +65,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<People>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.People
|
||||
.Where(_database.Like<People>(x => x.Name, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -71,14 +71,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc/>
|
||||
public override async Task<ICollection<Season>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.Seasons
|
||||
.Where(_database.Like<Season>(x => x.Name!, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -71,15 +71,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<Show>> Search(string query)
|
||||
{
|
||||
query = $"%{query}%";
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.Shows
|
||||
.Where(_database.Like<Show>(x => x.Name + " " + x.Slug, query))
|
||||
.Where(_database.Like<Show>(x => x.Name + " " + x.Slug, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -54,14 +54,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<Studio>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.Studios
|
||||
.Where(_database.Like<Studio>(x => x.Name, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -53,14 +53,12 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc />
|
||||
public override async Task<ICollection<User>> Search(string query)
|
||||
{
|
||||
return (await Sort(
|
||||
return await Sort(
|
||||
_database.Users
|
||||
.Where(_database.Like<User>(x => x.Username, $"%{query}%"))
|
||||
)
|
||||
.Take(20)
|
||||
.ToListAsync())
|
||||
.Select(SetBackingImageSelf)
|
||||
.ToList();
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -59,6 +59,8 @@ namespace Kyoo.Core.Api
|
||||
property.ShouldSerialize = _ =>
|
||||
{
|
||||
ICollection<string> fields = (ICollection<string>)_httpContextAccessor.HttpContext!.Items["fields"]!;
|
||||
if (fields == null)
|
||||
return false;
|
||||
return fields.Contains(member.Name);
|
||||
};
|
||||
}
|
||||
|
@ -19,10 +19,10 @@
|
||||
*/
|
||||
|
||||
import { z } from "zod";
|
||||
import { ImagesP, ResourceP } from "../traits";
|
||||
import { withImages, ResourceP } from "../traits";
|
||||
|
||||
export const CollectionP = ResourceP.merge(ImagesP)
|
||||
.extend({
|
||||
export const CollectionP = withImages(
|
||||
ResourceP.extend({
|
||||
/**
|
||||
* The title of this collection.
|
||||
*/
|
||||
@ -31,11 +31,12 @@ export const CollectionP = ResourceP.merge(ImagesP)
|
||||
* The summary of this show.
|
||||
*/
|
||||
overview: z.string().nullable(),
|
||||
})
|
||||
.transform((x) => ({
|
||||
...x,
|
||||
href: `/collection/${x.slug}`,
|
||||
}));
|
||||
}),
|
||||
"collections",
|
||||
).transform((x) => ({
|
||||
...x,
|
||||
href: `/collection/${x.slug}`,
|
||||
}));
|
||||
|
||||
/**
|
||||
* A class representing collections of show or movies.
|
||||
|
@ -20,72 +20,77 @@
|
||||
|
||||
import { z } from "zod";
|
||||
import { zdate } from "../utils";
|
||||
import { ImagesP, imageFn } from "../traits";
|
||||
import { withImages, imageFn } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
import { ShowP } from "./show";
|
||||
|
||||
const BaseEpisodeP = ResourceP.merge(ImagesP).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({
|
||||
const BaseEpisodeP = withImages(
|
||||
ResourceP.extend({
|
||||
/**
|
||||
* The direct link to the unprocessed video (pristine quality).
|
||||
* The season in witch this episode is in.
|
||||
*/
|
||||
direct: z.string().transform(imageFn),
|
||||
seasonNumber: z.number().nullable(),
|
||||
|
||||
/**
|
||||
* The link to an HLS master playlist containing all qualities available for this video.
|
||||
* The number of this episode in it's season.
|
||||
*/
|
||||
hls: z.string().transform(imageFn),
|
||||
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",
|
||||
);
|
||||
|
||||
export const EpisodeP = BaseEpisodeP.extend({
|
||||
/**
|
||||
* The episode that come before this one if you follow usual watch orders. If this is the first
|
||||
* episode or this is a movie, it will be null.
|
||||
*/
|
||||
previousEpisode: BaseEpisodeP.nullable().optional(),
|
||||
/**
|
||||
* The episode that come after this one if you follow usual watch orders. If this is the last
|
||||
* aired episode or this is a movie, it will be null.
|
||||
*/
|
||||
nextEpisode: BaseEpisodeP.nullable().optional(),
|
||||
export const EpisodeP = BaseEpisodeP.and(
|
||||
z.object({
|
||||
/**
|
||||
* The episode that come before this one if you follow usual watch orders. If this is the first
|
||||
* episode, it will be null.
|
||||
*/
|
||||
previousEpisode: BaseEpisodeP.nullable().optional(),
|
||||
/**
|
||||
* The episode that come after this one if you follow usual watch orders. If this is the last
|
||||
* aired episode, it will be null.
|
||||
*/
|
||||
nextEpisode: BaseEpisodeP.nullable().optional(),
|
||||
|
||||
show: ShowP.optional(),
|
||||
});
|
||||
show: ShowP.optional(),
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* A class to represent a single show's episode.
|
||||
|
@ -20,13 +20,13 @@
|
||||
|
||||
import { z } from "zod";
|
||||
import { zdate } from "../utils";
|
||||
import { ImagesP, ResourceP, imageFn } from "../traits";
|
||||
import { withImages, ResourceP, imageFn } from "../traits";
|
||||
import { Genre } from "./genre";
|
||||
import { StudioP } from "./studio";
|
||||
import { Status } from "./show";
|
||||
|
||||
export const MovieP = ResourceP.merge(ImagesP)
|
||||
.extend({
|
||||
export const MovieP = withImages(
|
||||
ResourceP.extend({
|
||||
/**
|
||||
* The title of this movie.
|
||||
*/
|
||||
@ -82,7 +82,9 @@ export const MovieP = ResourceP.merge(ImagesP)
|
||||
*/
|
||||
hls: z.string().transform(imageFn),
|
||||
}),
|
||||
})
|
||||
}),
|
||||
"movies",
|
||||
)
|
||||
.transform((x) => {
|
||||
if (!x.thumbnail && x.poster) {
|
||||
x.thumbnail = { ...x.poster };
|
||||
|
@ -19,26 +19,29 @@
|
||||
*/
|
||||
|
||||
import { z } from "zod";
|
||||
import { ImagesP } from "../traits";
|
||||
import { withImages } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const PersonP = ResourceP.merge(ImagesP).extend({
|
||||
/**
|
||||
* The name of this person.
|
||||
*/
|
||||
name: z.string(),
|
||||
/**
|
||||
* The type of work the person has done for the show. That can be something like "Actor",
|
||||
* "Writer", "Music", "Voice Actor"...
|
||||
*/
|
||||
type: z.string().optional(),
|
||||
export const PersonP = withImages(
|
||||
ResourceP.extend({
|
||||
/**
|
||||
* The name of this person.
|
||||
*/
|
||||
name: z.string(),
|
||||
/**
|
||||
* The type of work the person has done for the show. That can be something like "Actor",
|
||||
* "Writer", "Music", "Voice Actor"...
|
||||
*/
|
||||
type: z.string().optional(),
|
||||
|
||||
/**
|
||||
* The role the People played. This is mostly used to inform witch character was played for actor
|
||||
* and voice actors.
|
||||
*/
|
||||
role: z.string().optional(),
|
||||
});
|
||||
/**
|
||||
* The role the People played. This is mostly used to inform witch character was played for actor
|
||||
* and voice actors.
|
||||
*/
|
||||
role: z.string().optional(),
|
||||
}),
|
||||
"people",
|
||||
);
|
||||
|
||||
/**
|
||||
* A studio that make shows.
|
||||
|
@ -20,35 +20,38 @@
|
||||
|
||||
import { z } from "zod";
|
||||
import { zdate } from "../utils";
|
||||
import { ImagesP } from "../traits";
|
||||
import { withImages } from "../traits";
|
||||
import { ResourceP } from "../traits/resource";
|
||||
|
||||
export const SeasonP = ResourceP.merge(ImagesP).extend({
|
||||
/**
|
||||
* The name of this season.
|
||||
*/
|
||||
name: z.string(),
|
||||
/**
|
||||
* The number of this season. This can be set to 0 to indicate specials.
|
||||
*/
|
||||
seasonNumber: z.number(),
|
||||
/**
|
||||
* A quick overview of this season.
|
||||
*/
|
||||
overview: z.string().nullable(),
|
||||
/**
|
||||
* The starting air date of this season.
|
||||
*/
|
||||
startDate: zdate().nullable(),
|
||||
/**
|
||||
* The ending date of this season.
|
||||
*/
|
||||
endDate: zdate().nullable(),
|
||||
/**
|
||||
* The number of episodes available on kyoo of this season.
|
||||
*/
|
||||
episodesCount: z.number(),
|
||||
});
|
||||
export const SeasonP = withImages(
|
||||
ResourceP.extend({
|
||||
/**
|
||||
* The name of this season.
|
||||
*/
|
||||
name: z.string(),
|
||||
/**
|
||||
* The number of this season. This can be set to 0 to indicate specials.
|
||||
*/
|
||||
seasonNumber: z.number(),
|
||||
/**
|
||||
* A quick overview of this season.
|
||||
*/
|
||||
overview: z.string().nullable(),
|
||||
/**
|
||||
* The starting air date of this season.
|
||||
*/
|
||||
startDate: zdate().nullable(),
|
||||
/**
|
||||
* The ending date of this season.
|
||||
*/
|
||||
endDate: zdate().nullable(),
|
||||
/**
|
||||
* The number of episodes available on kyoo of this season.
|
||||
*/
|
||||
episodesCount: z.number(),
|
||||
}),
|
||||
"seasons",
|
||||
);
|
||||
|
||||
/**
|
||||
* A season of a Show.
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
import { z } from "zod";
|
||||
import { zdate } from "../utils";
|
||||
import { ImagesP, ResourceP } from "../traits";
|
||||
import { withImages, ResourceP } from "../traits";
|
||||
import { Genre } from "./genre";
|
||||
import { SeasonP } from "./season";
|
||||
import { StudioP } from "./studio";
|
||||
@ -35,8 +35,7 @@ export enum Status {
|
||||
Planned = "Planned",
|
||||
}
|
||||
|
||||
export const ShowP = ResourceP.merge(ImagesP)
|
||||
.extend({
|
||||
export const ShowP = withImages(ResourceP.extend({
|
||||
/**
|
||||
* The title of this show.
|
||||
*/
|
||||
@ -85,7 +84,7 @@ export const ShowP = ResourceP.merge(ImagesP)
|
||||
* The list of seasons of this show.
|
||||
*/
|
||||
seasons: z.array(SeasonP).optional(),
|
||||
})
|
||||
}), "shows")
|
||||
.transform((x) => {
|
||||
if (!x.thumbnail && x.poster) {
|
||||
x.thumbnail = { ...x.poster };
|
||||
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
import { Platform } from "react-native";
|
||||
import { z } from "zod";
|
||||
import { ZodObject, ZodRawShape, z } from "zod";
|
||||
import { kyooApiUrl } from "..";
|
||||
|
||||
export const imageFn = (url: string) => (Platform.OS === "web" ? `/api${url}` : kyooApiUrl + url);
|
||||
@ -27,12 +27,9 @@ export const imageFn = (url: string) => (Platform.OS === "web" ? `/api${url}` :
|
||||
export const Img = z.object({
|
||||
source: z.string(),
|
||||
blurhash: z.string(),
|
||||
low: z.string().transform(imageFn),
|
||||
medium: z.string().transform(imageFn),
|
||||
high: z.string().transform(imageFn),
|
||||
});
|
||||
|
||||
export const ImagesP = z.object({
|
||||
const ImagesP = z.object({
|
||||
/**
|
||||
* An url to the poster of this resource. If this resource does not have an image, the link will
|
||||
* be null. If the kyoo's instance is not capable of handling this kind of image for the specific
|
||||
@ -55,7 +52,28 @@ export const ImagesP = z.object({
|
||||
logo: Img.nullable(),
|
||||
});
|
||||
|
||||
const addQualities = (x: object | null | undefined, href: string) => {
|
||||
if (x === null) return null;
|
||||
return {
|
||||
...x,
|
||||
low: imageFn(`${href}?quality=low`),
|
||||
medium: imageFn(`${href}?quality=medium`),
|
||||
high: imageFn(`${href}?quality=high`),
|
||||
};
|
||||
};
|
||||
|
||||
export const withImages = <T extends ZodRawShape>(parser: ZodObject<T>, type: string) => {
|
||||
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`),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Base traits for items that has image resources.
|
||||
*/
|
||||
export type KyooImage = z.infer<typeof Img>;
|
||||
export type KyooImage = z.infer<typeof Img> & { low: string; medium: string; high: string };
|
||||
|
@ -98,7 +98,7 @@ SeasonHeader.query = (slug: string): QueryIdentifier<Season, SeasonProcessed> =>
|
||||
map: (seasons) =>
|
||||
seasons.reduce((acc, x) => {
|
||||
if (x.episodesCount == 0) return acc;
|
||||
return [...acc, { ...x, range: null, href: `/show/${slug}?season=${x.seasonNumber}` }];
|
||||
return [...acc, { ...x, href: `/show/${slug}?season=${x.seasonNumber}` }];
|
||||
}, [] as SeasonProcessed[]),
|
||||
},
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user