From 31a749b5ed70b4ad15f38adae2c03364d16185fc Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 11 Mar 2025 15:30:18 +0100 Subject: [PATCH] Add progress in `/series/:id?width=firstEntry` --- api/src/controllers/entries.ts | 7 ++++--- api/src/controllers/shows/logic.ts | 27 ++++++++++++++++++++++++--- api/src/db/schema/history.ts | 2 +- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index dc31f28a..22f0d25e 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -114,6 +114,7 @@ async function getEntries({ sort, filter, languages, + userId, }: { after: string | undefined; limit: number; @@ -121,6 +122,7 @@ async function getEntries({ sort: Sort; filter: SQL | undefined; languages: string[]; + userId: number; }): Promise<(Entry | Extra | UnknownEntry)[]> { const transQ = db .selectDistinctOn([entryTranslations.pk]) @@ -158,6 +160,7 @@ async function getEntries({ videoId: videos.id, }) .from(history) + .where(eq(history.profilePk, userId)) .leftJoin(videos, eq(history.videoPk, videos.pk)) .orderBy(history.entryPk, desc(history.playedDate)) .as("progress"); @@ -176,9 +179,7 @@ async function getEntries({ ...entryCol, ...transCol, videos: videosQ.videos, - progress: { - ...getColumns(progressQ), - }, + progress: getColumns(progressQ), // specials don't have an `episodeNumber` but a `number` field. number: episodeNumber, diff --git a/api/src/controllers/shows/logic.ts b/api/src/controllers/shows/logic.ts index 4d743df2..13c1d1cb 100644 --- a/api/src/controllers/shows/logic.ts +++ b/api/src/controllers/shows/logic.ts @@ -1,9 +1,10 @@ -import { type SQL, and, eq, exists, ne, sql } from "drizzle-orm"; +import { type SQL, and, desc, eq, exists, ne, sql } from "drizzle-orm"; import { db } from "~/db"; import { entries, entryTranslations, entryVideoJoin, + history, showStudioJoin, showTranslations, shows, @@ -144,7 +145,10 @@ const showRelations = { .leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk)) .as("videos"); }, - firstEntry: ({ languages }: { languages: string[] }) => { + firstEntry: ({ + languages, + userId, + }: { languages: string[]; userId: number }) => { const transQ = db .selectDistinctOn([entryTranslations.pk]) .from(entryTranslations) @@ -173,6 +177,19 @@ const showRelations = { .leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk)) .as("videos"); + const progressQ = db + .selectDistinctOn([history.entryPk], { + percent: history.percent, + time: history.time, + entryPk: history.entryPk, + videoId: videos.id, + }) + .from(history) + .where(eq(history.profilePk, userId)) + .leftJoin(videos, eq(history.videoPk, videos.pk)) + .orderBy(history.entryPk, desc(history.playedDate)) + .as("progress"); + return db .select({ firstEntry: jsonbBuildObject({ @@ -180,10 +197,12 @@ const showRelations = { ...transCol, number: entries.episodeNumber, videos: videosQ.videos, + progress: getColumns(progressQ), }).as("firstEntry"), }) .from(entries) .innerJoin(transQ, eq(entries.pk, transQ.pk)) + .leftJoin(progressQ, eq(entries.pk, progressQ.entryPk)) .leftJoinLateral(videosQ, sql`true`) .where(and(eq(entries.showPk, shows.pk), ne(entries.kind, "extra"))) .orderBy(entries.order) @@ -202,6 +221,7 @@ export async function getShows({ fallbackLanguage = true, preferOriginal = false, relations = [], + userId, }: { after?: string; limit: number; @@ -212,6 +232,7 @@ export async function getShows({ fallbackLanguage?: boolean; preferOriginal?: boolean; relations?: (keyof typeof showRelations)[]; + userId: number; }) { const transQ = db .selectDistinctOn([showTranslations.pk]) @@ -245,7 +266,7 @@ export async function getShows({ logo: sql`coalesce(nullif(${shows.original}->'logo', 'null'::jsonb), ${transQ.logo})`, }), - ...buildRelations(relations, showRelations, { languages }), + ...buildRelations(relations, showRelations, { languages, userId }), }) .from(shows) [fallbackLanguage ? "innerJoin" : ("leftJoin" as "innerJoin")]( diff --git a/api/src/db/schema/history.ts b/api/src/db/schema/history.ts index 4f7211e2..823e098a 100644 --- a/api/src/db/schema/history.ts +++ b/api/src/db/schema/history.ts @@ -1,5 +1,5 @@ import { sql } from "drizzle-orm"; -import { check, index, integer, jsonb, timestamp } from "drizzle-orm/pg-core"; +import { check, index, integer, timestamp } from "drizzle-orm/pg-core"; import { entries } from "./entries"; import { profiles } from "./profiles"; import { schema } from "./utils";