diff --git a/src/controllers/auth/anilist/getUser.ts b/src/controllers/auth/anilist/getUser.ts index 8d69580..67fad6c 100644 --- a/src/controllers/auth/anilist/getUser.ts +++ b/src/controllers/auth/anilist/getUser.ts @@ -2,6 +2,7 @@ import { graphql } from "gql.tada"; import { GraphQLClient } from "graphql-request"; import { sleep } from "~/libs/sleep"; +import type { User } from "~/types/user"; const GetUserQuery = graphql(` query GetUser { @@ -23,23 +24,6 @@ const GetUserQuery = graphql(` } `); -type User = { - statistics: { - minutesWatched?: number | undefined; - episodesWatched?: number | undefined; - count?: number | undefined; - meanScore?: number | undefined; - }; - name?: string | undefined; - avatar?: - | { - medium: string | null; - large: string | null; - } - | null - | undefined; -} | null; - export async function getUser(aniListToken: string): Promise { const client = new GraphQLClient("https://graphql.anilist.co/"); diff --git a/src/controllers/episodes/markEpisodeAsWatched/anilist.ts b/src/controllers/episodes/markEpisodeAsWatched/anilist.ts index b6da4e8..ea78d3c 100644 --- a/src/controllers/episodes/markEpisodeAsWatched/anilist.ts +++ b/src/controllers/episodes/markEpisodeAsWatched/anilist.ts @@ -8,7 +8,21 @@ const MarkEpisodeAsWatchedMutation = graphql(` status: CURRENT progress: $episodeNumber ) { - id + user { + name + avatar { + medium + large + } + statistics { + anime { + minutesWatched + episodesWatched + count + meanScore + } + } + } } } `); @@ -16,7 +30,21 @@ const MarkEpisodeAsWatchedMutation = graphql(` const MarkTitleAsWatchedMutation = graphql(` mutation MarkTitleAsWatched($titleId: Int!) { SaveMediaListEntry(mediaId: $titleId, status: COMPLETED) { - id + user { + name + avatar { + medium + large + } + statistics { + anime { + minutesWatched + episodesWatched + count + meanScore + } + } + } } } `); @@ -42,7 +70,10 @@ export async function markEpisodeAsWatched( ); return mutation - .then((data) => !!data?.SaveMediaListEntry?.id) + .then((data) => ({ + ...data?.SaveMediaListEntry?.user, + statistics: data?.SaveMediaListEntry?.user?.statistics?.anime, + })) .catch(async (err) => { console.error(await err.response); throw err; diff --git a/src/controllers/episodes/markEpisodeAsWatched/index.ts b/src/controllers/episodes/markEpisodeAsWatched/index.ts index d8a707b..5e4ca9a 100644 --- a/src/controllers/episodes/markEpisodeAsWatched/index.ts +++ b/src/controllers/episodes/markEpisodeAsWatched/index.ts @@ -8,9 +8,9 @@ import { EpisodeNumberSchema, ErrorResponse, ErrorResponseSchema, - SuccessResponse, SuccessResponseSchema, } from "~/types/schema"; +import { User } from "~/types/user"; import { markEpisodeAsWatched } from "./anilist"; @@ -39,7 +39,7 @@ const route = createRoute({ 200: { content: { "application/json": { - schema: SuccessResponseSchema(), + schema: SuccessResponseSchema(User), }, }, description: "Returns whether the episode was marked as watched", @@ -78,7 +78,7 @@ app.openapi(route, async (c) => { await c.req.json(); try { - await markEpisodeAsWatched( + const user = await markEpisodeAsWatched( aniListToken, aniListId, episodeNumber, @@ -93,13 +93,18 @@ app.openapi(route, async (c) => { "COMPLETED", ); } + + if (!user) { + console.error("Failed to mark episode as watched - user not found?"); + return c.json(ErrorResponse, { status: 500 }); + } + + return c.json({ success: true, result: user }, 200); } catch (error) { console.error("Failed to mark episode as watched"); console.error(error); return c.json(ErrorResponse, { status: 500 }); } - - return c.json(SuccessResponse, 200); }); export default app; diff --git a/src/types/user.ts b/src/types/user.ts new file mode 100644 index 0000000..4684465 --- /dev/null +++ b/src/types/user.ts @@ -0,0 +1,21 @@ +import { z } from "zod"; + +export type User = z.infer; +export const User = z + .object({ + statistics: z.object({ + minutesWatched: z.number().openapi({ type: "integer", format: "int64" }), + episodesWatched: z.number().openapi({ type: "integer", format: "int64" }), + count: z + .number() + .int() /* .openapi({ type: "integer", format: "int64" }) */, + meanScore: z.number().openapi({ type: "number", format: "float" }), + }), + name: z.string(), + avatar: z.object({ + medium: z.string(), + large: z.string(), + }), + }) + .optional() + .nullable();