Create part-of collection card

This commit is contained in:
Zoe Roux
2026-02-19 13:41:37 +01:00
parent 01f5b44b60
commit 31af752e2e
18 changed files with 264 additions and 197 deletions
+42 -1
View File
@@ -41,6 +41,8 @@ import {
getEntryTransQ,
mapProgress,
} from "../entries";
import { Collection } from "~/models/collections";
import { alias } from "drizzle-orm/pg-core";
export const watchStatusQ = db
.select({
@@ -124,6 +126,42 @@ export const showRelations = {
.where(eq(showTranslations.pk, shows.pk))
.as("translations");
},
collection: ({
languages,
preferOriginal,
}: {
languages: string[];
preferOriginal?: boolean;
}) => {
const collections = alias(shows, "collections");
const colTrans = alias(showTranslations, "col_trans");
const transQ = db
.selectDistinctOn([colTrans.pk])
.from(colTrans)
.orderBy(
colTrans.pk,
sql`array_position(${sqlarr(languages)}, ${colTrans.language})`,
)
.as("t");
return db
.select({
json: jsonbBuildObject<Collection>({
...getColumns(collections),
...getColumns(transQ),
...(preferOriginal && {
poster: sql<Image>`coalesce(nullif(${collections.original}->'poster', 'null'::jsonb), ${transQ.poster})`,
thumbnail: sql<Image>`coalesce(nullif(${collections.original}->'thumbnail', 'null'::jsonb), ${transQ.thumbnail})`,
banner: sql<Image>`coalesce(nullif(${collections.original}->'banner', 'null'::jsonb), ${transQ.banner})`,
logo: sql<Image>`coalesce(nullif(${collections.original}->'logo', 'null'::jsonb), ${transQ.logo})`,
}),
}),
})
.from(collections)
.innerJoin(transQ, eq(collections.pk, transQ.pk))
.where(eq(collections.pk, shows.collectionPk))
.as("collection");
},
studios: ({ languages }: { languages: string[] }) => {
const studioTransQ = db
.selectDistinctOn([studioTranslations.pk])
@@ -304,7 +342,10 @@ export async function getShows({
watchStatus: getColumns(watchStatusQ),
...buildRelations(relations, showRelations, { languages }),
...buildRelations(relations, showRelations, {
languages,
preferOriginal,
}),
})
.from(shows)
.leftJoin(watchStatusQ, eq(shows.pk, watchStatusQ.showPk))
+14 -8
View File
@@ -77,10 +77,13 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
preferOriginal: t.Optional(
t.Boolean({ description: desc.preferOriginal }),
),
with: t.Array(t.UnionEnum(["translations", "studios", "videos"]), {
default: [],
description: "Include related resources in the response.",
}),
with: t.Array(
t.UnionEnum(["translations", "collection", "studios", "videos"]),
{
default: [],
description: "Include related resources in the response.",
},
),
}),
headers: t.Object({
"accept-language": AcceptLanguage(),
@@ -119,10 +122,13 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
preferOriginal: t.Optional(
t.Boolean({ description: desc.preferOriginal }),
),
with: t.Array(t.UnionEnum(["translations", "studios", "videos"]), {
default: [],
description: "Include related resources in the response.",
}),
with: t.Array(
t.UnionEnum(["translations", "collection", "studios", "videos"]),
{
default: [],
description: "Include related resources in the response.",
},
),
}),
response: {
302: t.Void({
+14 -2
View File
@@ -78,7 +78,13 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
t.Boolean({ description: desc.preferOriginal }),
),
with: t.Array(
t.UnionEnum(["translations", "studios", "firstEntry", "nextEntry"]),
t.UnionEnum([
"translations",
"collection",
"studios",
"firstEntry",
"nextEntry",
]),
{
default: [],
description: "Include related resources in the response.",
@@ -123,7 +129,13 @@ export const series = new Elysia({ prefix: "/series", tags: ["series"] })
t.Boolean({ description: desc.preferOriginal }),
),
with: t.Array(
t.UnionEnum(["translations", "studios", "firstEntry", "nextEntry"]),
t.UnionEnum([
"translations",
"collection",
"studios",
"firstEntry",
"nextEntry",
]),
{
default: [],
description: "Include related resources in the response.",