aboutsummaryrefslogtreecommitdiff
path: root/src/lib/AniList
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-12-22 03:07:04 -0800
committerFuwn <[email protected]>2023-12-22 03:11:24 -0800
commita7255393ac86b091772189469fc1806ded1595d1 (patch)
treec238fcd2d5fa3302f195f9ee76d0d2dbbe1da43f /src/lib/AniList
parentfix(wrapped): absolute best updateWidth() (diff)
downloaddue.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.ts95
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;
+};