feat: create route to be able to mark episode as watched
This commit is contained in:
106
src/controllers/episodes/markEpisodeAsWatched/index.ts
Normal file
106
src/controllers/episodes/markEpisodeAsWatched/index.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
||||
import { env } from "hono/adapter";
|
||||
|
||||
import { updateWatchStatus } from "~/controllers/watch-status";
|
||||
import type { Env } from "~/types/env";
|
||||
import {
|
||||
AniListIdQuerySchema,
|
||||
EpisodeNumberSchema,
|
||||
ErrorResponse,
|
||||
ErrorResponseSchema,
|
||||
SuccessResponse,
|
||||
SuccessResponseSchema,
|
||||
} from "~/types/schema";
|
||||
|
||||
import { markEpisodeAsWatched } from "./anilist";
|
||||
|
||||
const MarkEpisodeAsWatchedRequest = z.object({
|
||||
episodeNumber: EpisodeNumberSchema,
|
||||
isComplete: z.boolean(),
|
||||
});
|
||||
|
||||
const route = createRoute({
|
||||
tags: ["aniplay", "episodes"],
|
||||
summary: "Mark episode as watched",
|
||||
operationId: "markEpisodeAsWatched",
|
||||
method: "post",
|
||||
path: "/{aniListId}/watched",
|
||||
request: {
|
||||
params: z.object({ aniListId: AniListIdQuerySchema }),
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: MarkEpisodeAsWatchedRequest,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: SuccessResponseSchema(),
|
||||
},
|
||||
},
|
||||
description: "Returns whether the episode was marked as watched",
|
||||
},
|
||||
401: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: ErrorResponseSchema,
|
||||
},
|
||||
},
|
||||
description: "Unauthorized to mark the episode as watched",
|
||||
},
|
||||
500: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: ErrorResponseSchema,
|
||||
},
|
||||
},
|
||||
description: "Error marking episode as watched",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const app = new OpenAPIHono<Env>();
|
||||
|
||||
app.openapi(route, async (c) => {
|
||||
const aniListToken = c.req.header("X-AniList-Token");
|
||||
|
||||
if (!aniListToken) {
|
||||
return c.json(ErrorResponse, { status: 401 });
|
||||
}
|
||||
|
||||
const deviceId = c.req.header("X-Aniplay-DeviceId")!;
|
||||
const aniListId = Number(c.req.param("aniListId"));
|
||||
const { episodeNumber, isComplete } =
|
||||
await c.req.json<typeof MarkEpisodeAsWatchedRequest._type>();
|
||||
|
||||
try {
|
||||
await markEpisodeAsWatched(
|
||||
aniListToken,
|
||||
aniListId,
|
||||
episodeNumber,
|
||||
isComplete,
|
||||
);
|
||||
if (isComplete) {
|
||||
await updateWatchStatus(
|
||||
env(c, "workerd"),
|
||||
c.req,
|
||||
deviceId,
|
||||
aniListId,
|
||||
"COMPLETED",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
new Error("Failed to mark episode as watched", { cause: error }),
|
||||
);
|
||||
return c.json(ErrorResponse, { status: 500 });
|
||||
}
|
||||
|
||||
return c.json(SuccessResponse, 200);
|
||||
});
|
||||
|
||||
export default app;
|
||||
Reference in New Issue
Block a user