diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index 1fb84b8a..ac0bd5d0 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -143,13 +143,16 @@ export const getEntryProgressQ = (userId: string) => export const mapProgress = ( progressQ: ReturnType, + { aliased }: { aliased: boolean } = { aliased: false }, ) => { const { time, percent, videoId } = getColumns(progressQ); - return { + const ret = { time: coalesce(time, sql`0`), percent: coalesce(percent, sql`0`), - videoId, + videoId: sql`${videoId}`, }; + if (!aliased) return ret; + return Object.fromEntries(Object.entries(ret).map(([k, v]) => [k, v.as(k)])); }; async function getEntries({ @@ -195,7 +198,7 @@ async function getEntries({ ...entryCol, ...transCol, videos: entryVideosQ.videos, - progress: mapProgress(entryProgressQ), + progress: mapProgress(entryProgressQ, { aliased: true }), // specials don't have an `episodeNumber` but a `number` field. number: episodeNumber, diff --git a/api/src/controllers/shows/shows.ts b/api/src/controllers/shows/shows.ts index a61983fb..397c4f43 100644 --- a/api/src/controllers/shows/shows.ts +++ b/api/src/controllers/shows/shows.ts @@ -1,5 +1,6 @@ import { and, isNull, sql } from "drizzle-orm"; import { Elysia, t } from "elysia"; +import { auth } from "~/auth"; import { prefix } from "~/base"; import { db } from "~/db"; import { shows } from "~/db/schema"; @@ -19,6 +20,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] }) .model({ show: Show, }) + .use(auth) .get( "random", async ({ error, redirect }) => { @@ -63,6 +65,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] }) }, headers: { "accept-language": languages }, request: { url }, + jwt: { sub }, }) => { const langs = processLanguages(languages); const items = await getShows({ @@ -76,6 +79,7 @@ export const showsH = new Elysia({ prefix: "/shows", tags: ["shows"] }) ), languages: langs, preferOriginal, + userId: sub, }); return createPage(items, { url, sort, limit }); }, diff --git a/api/src/controllers/staff.ts b/api/src/controllers/staff.ts index 4160d39e..b9184b59 100644 --- a/api/src/controllers/staff.ts +++ b/api/src/controllers/staff.ts @@ -1,15 +1,18 @@ import { type SQL, and, eq, sql } from "drizzle-orm"; import Elysia, { t } from "elysia"; +import { auth } from "~/auth"; import { prefix } from "~/base"; import { db } from "~/db"; -import { showTranslations, shows } from "~/db/schema"; +import { profiles, showTranslations, shows } from "~/db/schema"; import { roles, staff } from "~/db/schema/staff"; -import { getColumns, sqlarr } from "~/db/utils"; +import { watchlist } from "~/db/schema/watchlist"; +import { getColumns, jsonbBuildObject, sqlarr } from "~/db/utils"; import { KError } from "~/models/error"; import type { MovieStatus } from "~/models/movie"; import { Role, Staff } from "~/models/staff"; import { RoleWShow, RoleWStaff } from "~/models/staff-roles"; import { + AcceptLanguage, Filter, type FilterDef, type Image, @@ -22,6 +25,7 @@ import { sortToSql, } from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; +import type { WatchStatus } from "~/models/watchlist"; import { showFilters, showSort } from "./shows/logic"; const staffSort = Sort( @@ -113,6 +117,7 @@ export const staffH = new Elysia({ tags: ["staff"] }) staff: Staff, role: Role, }) + .use(auth) .get( "/staff/:id", async ({ params: { id }, error }) => { @@ -186,6 +191,7 @@ export const staffH = new Elysia({ tags: ["staff"] }) query: { limit, after, query, sort, filter, preferOriginal }, headers: { "accept-language": languages }, request: { url }, + jwt: { sub }, error, }) => { const [member] = await db @@ -210,6 +216,20 @@ export const staffH = new Elysia({ tags: ["staff"] }) sql`array_position(${sqlarr(langs)}, ${showTranslations.language})`, ) .as("t"); + + const watchStatusQ = db + .select({ + watchStatus: jsonbBuildObject({ + ...getColumns(watchlist), + percent: watchlist.seenCount, + }).as("watchStatus"), + }) + .from(watchlist) + .leftJoin(profiles, eq(watchlist.profilePk, profiles.pk)) + .where(and(eq(profiles.id, sub), eq(watchlist.showPk, shows.pk))) + .limit(1) + .as("watchstatus"); + const items = await db .select({ ...getColumns(roles), @@ -229,6 +249,7 @@ export const staffH = new Elysia({ tags: ["staff"] }) banner: sql`coalesce(nullif(${shows.original}->'banner', 'null'::jsonb), ${transQ.banner})`, logo: sql`coalesce(nullif(${shows.original}->'logo', 'null'::jsonb), ${transQ.logo})`, }), + watchStatus: sql`${watchStatusQ}`, }, }) .from(roles) @@ -278,6 +299,12 @@ export const staffH = new Elysia({ tags: ["staff"] }) }), ), }), + headers: t.Object( + { + "accept-language": AcceptLanguage(), + }, + { additionalProperties: true }, + ), response: { 200: Page(RoleWShow), 404: { diff --git a/api/src/models/watchlist.ts b/api/src/models/watchlist.ts index 0d5037b9..2b1f270d 100644 --- a/api/src/models/watchlist.ts +++ b/api/src/models/watchlist.ts @@ -52,3 +52,4 @@ export const WatchStatus = t.Object({ maximum: 100, }), }); +export type WatchStatus = typeof WatchStatus.static;