diff options
| author | Fuwn <[email protected]> | 2023-12-22 03:07:04 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2023-12-22 03:11:24 -0800 |
| commit | a7255393ac86b091772189469fc1806ded1595d1 (patch) | |
| tree | c238fcd2d5fa3302f195f9ee76d0d2dbbe1da43f /src/lib/AniList | |
| parent | fix(wrapped): absolute best updateWidth() (diff) | |
| download | due.moe-a7255393ac86b091772189469fc1806ded1595d1.tar.xz due.moe-a7255393ac86b091772189469fc1806ded1595d1.zip | |
feat(wrapped): full-year activity history
Diffstat (limited to 'src/lib/AniList')
| -rw-r--r-- | src/lib/AniList/activity.ts | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/src/lib/AniList/activity.ts b/src/lib/AniList/activity.ts index 1f99faca..a1bfedc6 100644 --- a/src/lib/AniList/activity.ts +++ b/src/lib/AniList/activity.ts @@ -1,4 +1,4 @@ -import type { UserIdentity } from './identity'; +import type { AniListAuthorisation, UserIdentity } from './identity'; export interface ActivityHistoryEntry { date: number; @@ -90,3 +90,96 @@ export const lastActivityDate = async (userIdentity: UserIdentity): Promise<Date return date; }; + +interface ActivitiesPage { + data: { + Page: { + pageInfo: { + hasNextPage: boolean; + }; + activities: { + createdAt: number; + }[]; + }; + }; +} + +const activitiesPage = async ( + page: number, + anilistAuthorisation: AniListAuthorisation, + userIdentity: UserIdentity +): Promise<ActivitiesPage> => + await ( + await fetch('https://graphql.anilist.co', { + method: 'POST', + headers: { + Authorization: `${anilistAuthorisation.tokenType} ${anilistAuthorisation.accessToken}`, + 'Content-Type': 'application/json', + Accept: 'application/json' + }, + body: JSON.stringify({ + query: `{ + Page(page: ${page}) { + pageInfo { hasNextPage } + activities(userId: ${userIdentity.id}, createdAt_greater: ${Math.floor( + new Date(new Date().getFullYear(), 0, 1).getTime() / 1000 + )}, createdAt_lesser: ${Math.floor( + new Date(new Date().getFullYear(), 6, 1).getTime() / 1000 + )}) { + ... on TextActivity { createdAt } + ... on ListActivity { createdAt } + ... on MessageActivity { createdAt } + } + } + }` + }) + }) + ).json(); + +export const fullActivityHistory = async ( + anilistAuthorisation: AniListAuthorisation, + userIdentity: UserIdentity +): Promise<ActivityHistoryEntry[]> => { + const activities: ActivityHistoryEntry[] = []; + let page = 1; + let currentPage = await activitiesPage(page, anilistAuthorisation, userIdentity); + + for (const activity of currentPage.data.Page.activities) activities.push(activity); + + while (currentPage['data']['Page']['pageInfo']['hasNextPage']) { + for (const activity of currentPage.data.Page.activities) activities.push(activity); + + page += 1; + currentPage = await activitiesPage(page, anilistAuthorisation, userIdentity); + } + + let fullLocalActivityHistory: ActivityHistoryEntry[] = []; + + for (const activity of activities) { + const date = new Date(activity.createdAt * 1000); + const dateString = date.toDateString(); + + const activityHistoryEntry = fullLocalActivityHistory.find( + (activityHistoryEntry) => + new Date(activityHistoryEntry.date * 1000).toDateString() === dateString + ); + + if (activityHistoryEntry) activityHistoryEntry.amount += 1; + else fullLocalActivityHistory.push({ date: Math.floor(date.getTime() / 1000), amount: 1 }); + } + + fullLocalActivityHistory = fullLocalActivityHistory.filter((a) => !isNaN(a.date)); + + fullLocalActivityHistory.push(...(await activityHistory(userIdentity))); + + fullLocalActivityHistory = fullLocalActivityHistory.filter( + (activityHistoryEntry, index, self) => + self.findIndex( + (a) => + new Date(a.date * 1000).toDateString() === + new Date(activityHistoryEntry.date * 1000).toDateString() + ) === index + ); + + return fullLocalActivityHistory; +}; |