From 32cc6e79103e20f5cca0e0979efd24476154dd7c Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 11 Mar 2025 17:16:56 +0100 Subject: [PATCH] Add watch status type in movies/series --- api/src/controllers/shows/logic.ts | 10 ++++++++++ api/src/db/schema/watchlist.ts | 12 ++++-------- api/src/models/movie.ts | 2 ++ api/src/models/serie.ts | 2 ++ api/src/models/watchlist.ts | 19 +++++++++++++++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/api/src/controllers/shows/logic.ts b/api/src/controllers/shows/logic.ts index 13c1d1cb..376b7b53 100644 --- a/api/src/controllers/shows/logic.ts +++ b/api/src/controllers/shows/logic.ts @@ -12,6 +12,7 @@ import { studios, videos, } from "~/db/schema"; +import { watchlist } from "~/db/schema/watchlist"; import { coalesce, getColumns, @@ -248,6 +249,12 @@ export async function getShows({ ) .as("t"); + const watchStatusQ = db + .select() + .from(watchlist) + .where(eq(watchlist.profilePk, userId)) + .as("watchstatus"); + return await db .select({ ...getColumns(shows), @@ -266,9 +273,12 @@ export async function getShows({ logo: sql`coalesce(nullif(${shows.original}->'logo', 'null'::jsonb), ${transQ.logo})`, }), + watchStatus: getColumns(watchStatusQ), + ...buildRelations(relations, showRelations, { languages, userId }), }) .from(shows) + .leftJoin(watchStatusQ, eq(shows.pk, watchStatusQ.showPk)) [fallbackLanguage ? "innerJoin" : ("leftJoin" as "innerJoin")]( transQ, eq(shows.pk, transQ.pk), diff --git a/api/src/db/schema/watchlist.ts b/api/src/db/schema/watchlist.ts index 0699134f..a00d7967 100644 --- a/api/src/db/schema/watchlist.ts +++ b/api/src/db/schema/watchlist.ts @@ -1,11 +1,5 @@ import { sql } from "drizzle-orm"; -import { - check, - integer, - primaryKey, - text, - timestamp, -} from "drizzle-orm/pg-core"; +import { check, integer, primaryKey, timestamp } from "drizzle-orm/pg-core"; import { entries } from "./entries"; import { profiles } from "./profiles"; import { shows } from "./shows"; @@ -34,7 +28,9 @@ export const watchlist = schema.table( nextEntry: integer().references(() => entries.pk, { onDelete: "set null" }), score: integer(), - notes: text(), + + startedAt: timestamp({ withTimezone: true, mode: "string" }), + completedAt: timestamp({ withTimezone: true, mode: "string" }), createdAt: timestamp({ withTimezone: true, mode: "string" }) .notNull() diff --git a/api/src/models/movie.ts b/api/src/models/movie.ts index 326f203a..4110f000 100644 --- a/api/src/models/movie.ts +++ b/api/src/models/movie.ts @@ -16,6 +16,7 @@ import { } from "./utils"; import { Original } from "./utils/original"; import { EmbeddedVideo } from "./video"; +import { WatchStatus } from "./watchlist"; export const MovieStatus = t.UnionEnum(["unknown", "finished", "planned"]); export type MovieStatus = typeof MovieStatus.static; @@ -55,6 +56,7 @@ export const Movie = t.Intersect([ t.Object({ original: Original, isAvailable: t.Boolean(), + watchStatus: t.Omit(WatchStatus, ["seenCount"]), }), ]); export type Movie = Prettify; diff --git a/api/src/models/serie.ts b/api/src/models/serie.ts index 1b664bbc..a24fcec9 100644 --- a/api/src/models/serie.ts +++ b/api/src/models/serie.ts @@ -17,6 +17,7 @@ import { TranslationRecord, } from "./utils"; import { Original } from "./utils/original"; +import { WatchStatus } from "./watchlist"; export const SerieStatus = t.UnionEnum([ "unknown", @@ -70,6 +71,7 @@ export const Serie = t.Intersect([ availableCount: t.Integer({ description: "The number of episodes that can be played right away", }), + watchStatus: WatchStatus, }), ]); export type Serie = Prettify; diff --git a/api/src/models/watchlist.ts b/api/src/models/watchlist.ts index a70924cf..daf4ca49 100644 --- a/api/src/models/watchlist.ts +++ b/api/src/models/watchlist.ts @@ -27,3 +27,22 @@ export const Progress = t.Object({ ), }); export type Progress = typeof Progress.static; + +export const WatchlistStatus = t.UnionEnum([ + "completed", + "watching", + "rewatching", + "dropped", + "planned", +]); + +export const WatchStatus = t.Object({ + status: WatchlistStatus, + score: t.Nullable(t.Integer({ minimum: 0, maximum: 100 })), + startedAt: t.Nullable(t.String({ format: "date-time" })), + completedAt: t.Nullable(t.String({ format: "date-time" })), + seenCount: t.Integer({ + description: "The number of episodes you watched in this serie.", + minimum: 0, + }), +});