From e1af2369964e0e5eed8fed9d86a89b8547559251 Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Mon, 8 Jul 2024 19:11:47 -0700
Subject: feat(pwa): anilist notifications

---
 src/routes/+layout.svelte | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

(limited to 'src/routes/+layout.svelte')

diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 1c849fca..a34b24b1 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -11,7 +11,7 @@
 	import { readable, type Readable } from 'svelte/store';
 	import { navigating } from '$app/stores';
 	import Notifications from 'svelte-notifications';
-	import Notification from '$lib/Notification/Notification.svelte';
+	import * as EventNotification from '$lib/Notification/Notification.svelte';
 	import Root from '$lib/Home/Root.svelte';
 	import root from '$lib/Utility/root';
 	import { addMessages, init, locale as i18nLocale, locales } from 'svelte-i18n';
@@ -28,6 +28,7 @@
 	import settingsSyncTimes from '$stores/settingsSyncTimes';
 	import Announcement from '$lib/Announcement.svelte';
 	import Message from '$lib/Loading/Message.svelte';
+	import { notifications } from '$lib/Data/AniList/notifications';
 
 	injectSpeedInsights();
 
@@ -35,6 +36,8 @@
 
 	let isHeaderVisible = true;
 	let previousScrollPosition = 0;
+	let notificationInterval: NodeJS.Timeout | undefined = undefined;
+	let lastNotificationId = 0;
 
 	addMessages('en', english as unknown as LocaleDictionary);
 	addMessages('ja', japanese as unknown as LocaleDictionary);
@@ -106,10 +109,45 @@
 						}
 					});
 			});
+
+		if ($settings.displayAniListNotifications && data.user !== undefined) {
+			if ('Notification' in window && navigator.serviceWorker) Notification.requestPermission();
+
+			if (window.matchMedia('(display-mode: standalone)').matches) {
+				notificationInterval = setInterval(async () => {
+					try {
+						const recentNotifications = await notifications(data.user.accessToken);
+
+						if (
+							recentNotifications &&
+							recentNotifications.length > 0 &&
+							recentNotifications[0].id > lastNotificationId &&
+							new Date(recentNotifications[0].createdAt * 1000).getTime() + 30000 >
+								new Date().getTime()
+						) {
+							lastNotificationId = recentNotifications[0].id;
+
+							if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
+								navigator.serviceWorker.ready.then((registration) => {
+									registration.showNotification('due.moe', {
+										body: `${recentNotifications[0].user.name}${recentNotifications[0].context}`,
+										icon: recentNotifications[0].user.avatar.large || '/favicon-196x196.png'
+									});
+								});
+							}
+						}
+					} catch (error) {
+						console.error(error);
+					}
+				}, 15000);
+			}
+		}
 	});
 
 	onDestroy(() => {
 		if (browser) window.removeEventListener('scroll', handleScroll);
+
+		if (notificationInterval) clearInterval(notificationInterval);
 	});
 
 	$: {
@@ -229,7 +267,7 @@
 
 		<p />
 
-		<Notifications item={Notification} zIndex={5000}>
+		<Notifications item={EventNotification} zIndex={5000}>
 			<Root {data} {way}>
 				{#if $userIdentity.id !== -1}
 					<slot />
-- 
cgit v1.2.3

