mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-05-22 15:12:28 -04:00
Fix watchlist apis & add delete watchlist api
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
import { db } from "~/db";
|
||||
import { entries, shows } from "~/db/schema";
|
||||
import { watchlist } from "~/db/schema/watchlist";
|
||||
import { conflictUpdateAllExcept, getColumns } from "~/db/utils";
|
||||
import { coalesce, getColumns, rowToModel } from "~/db/utils";
|
||||
import { Entry } from "~/models/entry";
|
||||
import { KError } from "~/models/error";
|
||||
import { bubble, madeInAbyss } from "~/models/examples";
|
||||
@@ -26,9 +26,16 @@ import {
|
||||
processLanguages,
|
||||
} from "~/models/utils";
|
||||
import { desc } from "~/models/utils/descriptions";
|
||||
import { MovieWatchStatus, SerieWatchStatus } from "~/models/watchlist";
|
||||
import {
|
||||
MovieWatchStatus,
|
||||
SeedMovieWatchStatus,
|
||||
SeedSerieWatchStatus,
|
||||
SerieWatchStatus,
|
||||
} from "~/models/watchlist";
|
||||
import { getOrCreateProfile } from "./profile";
|
||||
|
||||
console.log();
|
||||
|
||||
async function setWatchStatus({
|
||||
show,
|
||||
status,
|
||||
@@ -37,7 +44,7 @@ async function setWatchStatus({
|
||||
show:
|
||||
| { pk: number; kind: "movie" }
|
||||
| { pk: number; kind: "serie"; entriesCount: number };
|
||||
status: Omit<SerieWatchStatus, "seenCount">;
|
||||
status: SeedSerieWatchStatus;
|
||||
userId: string;
|
||||
}) {
|
||||
const profilePk = await getOrCreateProfile(userId);
|
||||
@@ -53,6 +60,7 @@ async function setWatchStatus({
|
||||
.insert(watchlist)
|
||||
.values({
|
||||
...status,
|
||||
startedAt: coalesce(sql`${status.startedAt ?? null}`, sql`now()`),
|
||||
profilePk: profilePk,
|
||||
seenCount:
|
||||
status.status === "completed"
|
||||
@@ -70,38 +78,33 @@ async function setWatchStatus({
|
||||
.onConflictDoUpdate({
|
||||
target: [watchlist.profilePk, watchlist.showPk],
|
||||
set: {
|
||||
...conflictUpdateAllExcept(watchlist, [
|
||||
"profilePk",
|
||||
"showPk",
|
||||
"createdAt",
|
||||
"seenCount",
|
||||
"nextEntry",
|
||||
"lastPlayedAt",
|
||||
]),
|
||||
...(status.status === "completed"
|
||||
? {
|
||||
seenCount: sql`excluded.seen_count`,
|
||||
nextEntry: sql`null`,
|
||||
}
|
||||
: {}),
|
||||
status: sql`excluded.status`,
|
||||
startedAt: coalesce(
|
||||
sql`${status.startedAt ?? null}`,
|
||||
watchlist.startedAt,
|
||||
),
|
||||
completedAt: sql`
|
||||
case
|
||||
when excluded.status = 'completed' then coalesce(excluded.completed_at, now())
|
||||
else coalesce(excluded.completed_at, ${watchlist.completedAt})
|
||||
end
|
||||
`,
|
||||
// only set seenCount & nextEntry when marking as "rewatching"
|
||||
// if it's already rewatching, the history updates are more up-dated.
|
||||
...(status.status === "rewatching"
|
||||
? {
|
||||
seenCount: sql`
|
||||
case when ${watchlist.status} != 'rewatching'
|
||||
then excluded.seen_count
|
||||
else
|
||||
${watchlist.seenCount}
|
||||
end`,
|
||||
nextEntry: sql`
|
||||
case when ${watchlist.status} != 'rewatching'
|
||||
then excluded.next_entry
|
||||
else
|
||||
${watchlist.nextEntry}
|
||||
end`,
|
||||
}
|
||||
: {}),
|
||||
seenCount: sql`
|
||||
case
|
||||
when excluded.status = 'completed' then excluded.seen_count
|
||||
when excluded.status = 'rewatching' and ${watchlist.status} != 'rewatching' then excluded.seen_count
|
||||
else ${watchlist.seenCount}
|
||||
end
|
||||
`,
|
||||
nextEntry: sql`
|
||||
case
|
||||
when excluded.status = 'completed' then null
|
||||
when excluded.status = 'rewatching' and ${watchlist.status} != 'rewatching' then excluded.next_entry
|
||||
else ${watchlist.nextEntry}
|
||||
end
|
||||
`,
|
||||
},
|
||||
})
|
||||
.returning({
|
||||
@@ -296,7 +299,7 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
|
||||
example: madeInAbyss.slug,
|
||||
}),
|
||||
}),
|
||||
body: t.Omit(SerieWatchStatus, ["seenCount"]),
|
||||
body: SeedSerieWatchStatus,
|
||||
response: {
|
||||
200: t.Intersect([SerieWatchStatus, DbMetadata]),
|
||||
404: KError,
|
||||
@@ -341,7 +344,88 @@ export const watchlistH = new Elysia({ tags: ["profiles"] })
|
||||
example: bubble.slug,
|
||||
}),
|
||||
}),
|
||||
body: t.Omit(MovieWatchStatus, ["percent"]),
|
||||
body: SeedMovieWatchStatus,
|
||||
response: {
|
||||
200: t.Intersect([MovieWatchStatus, DbMetadata]),
|
||||
404: KError,
|
||||
},
|
||||
permissions: ["core.read"],
|
||||
},
|
||||
)
|
||||
.delete(
|
||||
"/series/:id/watchstatus",
|
||||
async ({ params: { id }, jwt: { sub }, status }) => {
|
||||
const profilePk = await getOrCreateProfile(sub);
|
||||
|
||||
const rows = await db.execute(sql`
|
||||
delete from ${watchlist} using ${shows}
|
||||
where ${and(
|
||||
eq(watchlist.profilePk, profilePk),
|
||||
eq(watchlist.showPk, shows.pk),
|
||||
eq(shows.kind, "serie"),
|
||||
isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id),
|
||||
)}
|
||||
returning ${watchlist}.*
|
||||
`);
|
||||
|
||||
if (rows.rowCount === 0) {
|
||||
return status(404, {
|
||||
status: 404,
|
||||
message: `No serie found in your watchlist the id/slug: '${id}'.`,
|
||||
});
|
||||
}
|
||||
|
||||
return rowToModel(rows.rows[0], watchlist);
|
||||
},
|
||||
{
|
||||
detail: { description: "Set watchstatus of a serie." },
|
||||
params: t.Object({
|
||||
id: t.String({
|
||||
description: "The id or slug of the serie.",
|
||||
example: madeInAbyss.slug,
|
||||
}),
|
||||
}),
|
||||
response: {
|
||||
200: t.Intersect([SerieWatchStatus, DbMetadata]),
|
||||
404: KError,
|
||||
},
|
||||
permissions: ["core.read"],
|
||||
},
|
||||
)
|
||||
.delete(
|
||||
"/movies/:id/watchstatus",
|
||||
async ({ params: { id }, jwt: { sub }, status }) => {
|
||||
const profilePk = await getOrCreateProfile(sub);
|
||||
|
||||
const rows = await db.execute(sql`
|
||||
delete from ${watchlist} using ${shows}
|
||||
where ${and(
|
||||
eq(watchlist.profilePk, profilePk),
|
||||
eq(watchlist.showPk, shows.pk),
|
||||
eq(shows.kind, "movie"),
|
||||
isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id),
|
||||
)}
|
||||
returning ${watchlist}.*
|
||||
`);
|
||||
|
||||
if (rows.rowCount === 0) {
|
||||
return status(404, {
|
||||
status: 404,
|
||||
message: `No movie found in your watchlist the id/slug: '${id}'.`,
|
||||
});
|
||||
}
|
||||
|
||||
const ret = rowToModel(rows.rows[0], watchlist);
|
||||
return { ...ret, percent: ret.seenCount };
|
||||
},
|
||||
{
|
||||
detail: { description: "Set watchstatus of a movie." },
|
||||
params: t.Object({
|
||||
id: t.String({
|
||||
description: "The id or slug of the movie.",
|
||||
example: bubble.slug,
|
||||
}),
|
||||
}),
|
||||
response: {
|
||||
200: t.Intersect([MovieWatchStatus, DbMetadata]),
|
||||
404: KError,
|
||||
|
||||
Reference in New Issue
Block a user