From 84378e77580c5caaa84aaa2cf7aeb512bf49bc60 Mon Sep 17 00:00:00 2001 From: zaanposni Date: Sat, 30 Nov 2024 21:03:20 +0100 Subject: [PATCH] auto reload frontpage every 5minutes --- src/psaggregator/src/routes/+page.svelte | 100 +++++++++++++++++- .../src/routes/changelog/+page.svelte | 23 ++-- 2 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/psaggregator/src/routes/+page.svelte b/src/psaggregator/src/routes/+page.svelte index 098fd74..54ac575 100644 --- a/src/psaggregator/src/routes/+page.svelte +++ b/src/psaggregator/src/routes/+page.svelte @@ -9,11 +9,105 @@ import MediaQuery from "$lib/utils/MediaQuery.svelte"; import InstagramPost from "$lib/components/InstagramPost.svelte"; import TwitchEntry from "$lib/components/TwitchEntry.svelte"; - import { version } from "$app/environment"; + import { browser, version } from "$app/environment"; import TwitterPost from "$lib/components/TwitterPost.svelte"; - import { GITHUB_URL, MAIL_TO_URL } from "../config/config"; + import { GITHUB_URL, LOW_DATA_MODE, MAIL_TO_URL } from "../config/config"; + import { invalidateAll } from "$app/navigation"; + import { onDestroy, onMount } from "svelte"; + import FaviconNotification from "favicon-notification"; + import type { ContentPiece, Information, ScheduledContentPiece } from "@prisma/client"; + import moment from "moment"; export let data: PageServerData; + + let reloadInterval: number | NodeJS.Timeout | undefined = undefined; + let isNotificationVisible = false; + + function findNewestDate() { + const dates = [ + ...(data.today?.map((entry: ScheduledContentPiece) => moment(entry.startDate)) ?? []), + ...(data.youtubeCommunityPosts?.map((entry: Information) => moment(entry.date)) ?? []), + ...(data.instagramPosts?.map((entry: Information) => moment(entry.date)) ?? []), + ...(data.twitterPosts?.map((entry: Information) => moment(entry.date)) ?? []), + ...(data.redditPosts?.map((entry: RedditPost) => moment(entry.date)) ?? []), + ...(data.videos?.map((entry: ContentPiece) => moment(entry.startDate)) ?? []), + ...(data.upcomingStreams?.map((entry: ScheduledContentPiece) => moment(entry.startDate)) ?? []), + moment((data.twitchStatus as TwitchStatus)?.startedAt ?? 0) + ]; + + return Math.max(...dates); + } + + async function reload() { + if ($LOW_DATA_MODE) return; + + const currentLastDate = findNewestDate(); + const currentLastUploadPlanEntriesWithLink = data.today.filter((entry: ScheduledContentPiece) => entry.href).length; + + await invalidateAll(); + + const newLastDate = findNewestDate(); + const newUploadPlanEntriesWithLink = data.today.filter((entry: ScheduledContentPiece) => entry.href).length; + + if ( + (currentLastDate !== newLastDate && currentLastDate && newLastDate) || + currentLastUploadPlanEntriesWithLink !== newUploadPlanEntriesWithLink + ) { + isNotificationVisible = true; + try { + FaviconNotification.add(); + } catch (e) { + console.error(e); + } + } + } + + function onUserActive() { + if (!isNotificationVisible) return; + + isNotificationVisible = false; + try { + FaviconNotification.remove(); + } catch (e) { + console.error(e); + } + } + + function handleVisibilityChange() { + if (document.visibilityState === "visible") { + onUserActive(); + } + } + + function handleUserInteraction() { + onUserActive(); + } + + onMount(() => { + if (browser) { + reloadInterval = setInterval(reload, 1000 * 60 * 5); + + FaviconNotification.init({ + color: "#ff0000", + lineColor: "#000000", + url: "/favicon.png" + }); + + document.addEventListener("visibilitychange", handleVisibilityChange); + window.addEventListener("mousemove", handleUserInteraction); + window.addEventListener("focus", handleUserInteraction); + } + }); + + onDestroy(() => { + if (browser) { + if (reloadInterval) clearInterval(reloadInterval); + + document.removeEventListener("visibilitychange", handleVisibilityChange); + window.removeEventListener("mousemove", handleUserInteraction); + window.removeEventListener("focus", handleUserInteraction); + } + });