diff --git a/back/src/Kyoo.Abstractions/Models/News.cs b/back/src/Kyoo.Abstractions/Models/News.cs index f42cf624..bb5351d8 100644 --- a/back/src/Kyoo.Abstractions/Models/News.cs +++ b/back/src/Kyoo.Abstractions/Models/News.cs @@ -159,7 +159,7 @@ namespace Kyoo.Abstractions.Models /// A simple summary of informations about the show of this episode /// (this is specially useful since news can't have includes). /// - public class ShowInfo : IResource + public class ShowInfo : IResource, IThumbnails { /// public int Id { get; set; } @@ -171,6 +171,15 @@ namespace Kyoo.Abstractions.Models /// The title of this show. /// public string Name { get; set; } + + /// + public Image? Poster { get; set; } + + /// + public Image? Thumbnail { get; set; } + + /// + public Image? Logo { get; set; } } } } diff --git a/back/src/Kyoo.Postgresql/DatabaseContext.cs b/back/src/Kyoo.Postgresql/DatabaseContext.cs index 1c53ae89..996139cc 100644 --- a/back/src/Kyoo.Postgresql/DatabaseContext.cs +++ b/back/src/Kyoo.Postgresql/DatabaseContext.cs @@ -361,8 +361,11 @@ namespace Kyoo.Postgresql modelBuilder.Entity() .Ignore(x => x.Links); - modelBuilder.Entity() + var builder = modelBuilder.Entity() .OwnsOne(x => x.Show); + builder.OwnsOne(x => x.Poster); + builder.OwnsOne(x => x.Thumbnail); + builder.OwnsOne(x => x.Logo); } /// diff --git a/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.Designer.cs b/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.Designer.cs index 3464cf84..318bd082 100644 --- a/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.Designer.cs +++ b/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.Designer.cs @@ -1197,6 +1197,119 @@ namespace Kyoo.Postgresql.Migrations modelBuilder.Entity("Kyoo.Abstractions.Models.News", b => { + b.OwnsOne("Kyoo.Abstractions.Models.News+ShowInfo", "Show", b1 => + { + b1.Property("NewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b1.Property("Id") + .HasColumnType("integer") + .HasColumnName("show_id"); + + b1.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_name"); + + b1.Property("Slug") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_slug"); + + b1.HasKey("NewsId"); + + b1.ToTable("news"); + + b1.WithOwner() + .HasForeignKey("NewsId") + .HasConstraintName("fk_news_news_id"); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_logo_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_logo_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Poster", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_poster_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_poster_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Thumbnail", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_thumbnail_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_thumbnail_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.Navigation("Logo"); + + b1.Navigation("Poster"); + + b1.Navigation("Thumbnail"); + }); + b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 => { b1.Property("NewsId") @@ -1275,35 +1388,6 @@ namespace Kyoo.Postgresql.Migrations .HasConstraintName("fk_news_news_id"); }); - b.OwnsOne("Kyoo.Abstractions.Models.ShowInfo", "Show", b1 => - { - b1.Property("NewsId") - .HasColumnType("integer") - .HasColumnName("id"); - - b1.Property("Id") - .HasColumnType("integer") - .HasColumnName("show_info_id"); - - b1.Property("Name") - .IsRequired() - .HasColumnType("text") - .HasColumnName("show_info_name"); - - b1.Property("Slug") - .IsRequired() - .HasColumnType("text") - .HasColumnName("show_info_slug"); - - b1.HasKey("NewsId"); - - b1.ToTable("news"); - - b1.WithOwner() - .HasForeignKey("NewsId") - .HasConstraintName("fk_news_news_id"); - }); - b.Navigation("Logo"); b.Navigation("Poster"); diff --git a/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.cs b/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.cs index 926f1f04..1c07f9c1 100644 --- a/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.cs +++ b/back/src/Kyoo.Postgresql/Migrations/20231029233109_news.cs @@ -38,7 +38,9 @@ namespace Kyoo.Postgresql.Migrations e.id, e.slug, e.name, NULL AS tagline, '{}' AS aliases, e.path, e.overview, '{}' AS tags, '{}' AS genres, NULL AS status, e.release_date AS air_date, e.poster_source, e.poster_blurhash, e.thumbnail_source, e.thumbnail_blurhash, e.logo_source,e.logo_blurhash, NULL AS trailer, e.external_id, e.season_number, e.episode_number, e.absolute_number, - 'episode'::news_kind AS kind, e.added_date, s.id AS show_id, s.slug AS show_slug, s.name AS show_name + 'episode'::news_kind AS kind, e.added_date, s.id AS show_id, s.slug AS show_slug, s.name AS show_name, + s.poster_source AS show_poster_source, s.poster_blurhash AS show_poster_blurhash, s.thumbnail_source AS show_thumbnail_source, + s.thumbnail_blurhash AS show_thumbnail_blurhash, s.logo_source AS show_logo_source, s.logo_blurhash AS show_logo_blurhash FROM episodes AS e LEFT JOIN shows AS s ON e.show_id = s.id UNION ALL @@ -46,7 +48,9 @@ namespace Kyoo.Postgresql.Migrations -m.id, m.slug, m.name, m.tagline, m.aliases, m.path, m.overview, m.tags, m.genres, m.status, m.air_date, m.poster_source, m.poster_blurhash, m.thumbnail_source, m.thumbnail_blurhash, m.logo_source, m.logo_blurhash, m.trailer, m.external_id, NULL AS season_number, NULL AS episode_number, NULL as absolute_number, - 'movie'::news_kind AS kind, m.added_date, NULL AS show_id, NULL AS show_slug, NULL AS show_name + 'movie'::news_kind AS kind, m.added_date, NULL AS show_id, NULL AS show_slug, NULL AS show_name, + NULL AS show_poster_source, NULL AS show_poster_blurhash, NULL AS show_thumbnail_source, NULL AS show_thumbnail_blurhash, + NULL AS show_logo_source, NULL AS show_logo_blurhash FROM movies AS m "); } diff --git a/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs b/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs index 4f4bb873..accbb6cb 100644 --- a/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs +++ b/back/src/Kyoo.Postgresql/Migrations/PostgresContextModelSnapshot.cs @@ -1,4 +1,4 @@ -// +// using System; using System.Collections.Generic; using Kyoo.Abstractions.Models; @@ -1194,6 +1194,119 @@ namespace Kyoo.Postgresql.Migrations modelBuilder.Entity("Kyoo.Abstractions.Models.News", b => { + b.OwnsOne("Kyoo.Abstractions.Models.News+ShowInfo", "Show", b1 => + { + b1.Property("NewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b1.Property("Id") + .HasColumnType("integer") + .HasColumnName("show_id"); + + b1.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_name"); + + b1.Property("Slug") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_slug"); + + b1.HasKey("NewsId"); + + b1.ToTable("news"); + + b1.WithOwner() + .HasForeignKey("NewsId") + .HasConstraintName("fk_news_news_id"); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_logo_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_logo_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Poster", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_poster_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_poster_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.OwnsOne("Kyoo.Abstractions.Models.Image", "Thumbnail", b2 => + { + b2.Property("ShowInfoNewsId") + .HasColumnType("integer") + .HasColumnName("id"); + + b2.Property("Blurhash") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("show_thumbnail_blurhash"); + + b2.Property("Source") + .IsRequired() + .HasColumnType("text") + .HasColumnName("show_thumbnail_source"); + + b2.HasKey("ShowInfoNewsId"); + + b2.ToTable("news"); + + b2.WithOwner() + .HasForeignKey("ShowInfoNewsId") + .HasConstraintName("fk_news_news_id"); + }); + + b1.Navigation("Logo"); + + b1.Navigation("Poster"); + + b1.Navigation("Thumbnail"); + }); + b.OwnsOne("Kyoo.Abstractions.Models.Image", "Logo", b1 => { b1.Property("NewsId") @@ -1272,35 +1385,6 @@ namespace Kyoo.Postgresql.Migrations .HasConstraintName("fk_news_news_id"); }); - b.OwnsOne("Kyoo.Abstractions.Models.ShowInfo", "Show", b1 => - { - b1.Property("NewsId") - .HasColumnType("integer") - .HasColumnName("id"); - - b1.Property("Id") - .HasColumnType("integer") - .HasColumnName("show_info_id"); - - b1.Property("Name") - .IsRequired() - .HasColumnType("text") - .HasColumnName("show_info_name"); - - b1.Property("Slug") - .IsRequired() - .HasColumnType("text") - .HasColumnName("show_info_slug"); - - b1.HasKey("NewsId"); - - b1.ToTable("news"); - - b1.WithOwner() - .HasForeignKey("NewsId") - .HasConstraintName("fk_news_news_id"); - }); - b.Navigation("Logo"); b.Navigation("Poster"); diff --git a/front/packages/models/src/resources/news.ts b/front/packages/models/src/resources/news.ts index 521b0b00..e7ab99ed 100644 --- a/front/packages/models/src/resources/news.ts +++ b/front/packages/models/src/resources/news.ts @@ -22,6 +22,7 @@ import { z } from "zod"; import { MovieP } from "./movie"; import { BaseEpisodeP } from "./episode"; import { ResourceP } from "../traits/resource"; +import { withImages } from "../traits/images"; /** * The type of item, ether a a movie or an episode. @@ -38,11 +39,26 @@ export const NewsP = z.union([ BaseEpisodeP.and( z.object({ kind: z.literal(NewsKind.Episode), - show: ResourceP.extend({ - name: z.string(), + show: withImages( + ResourceP.extend({ + name: z.string(), + }), + "shows", + ).transform((x) => { + if (!x.thumbnail && x.poster) { + x.thumbnail = { ...x.poster }; + if (x.thumbnail) { + x.thumbnail.low = x.thumbnail.high; + x.thumbnail.medium = x.thumbnail.high; + } + } + return x; }), }), - ), + ).transform((x) => { + if (!x.thumbnail && x.show.thumbnail) x.thumbnail = x.show.thumbnail; + return x; + }), /* * Or a Movie */