diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 1f2db6e..86c3fcb 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -1270,7 +1270,8 @@ img { max-width: 100%; display: block; } transition: opacity 0.6s ease, visibility 0.6s ease; } -.loader.hidden { +.loader.hidden, +.loader.loader-done { opacity: 0; visibility: hidden; pointer-events: none; @@ -7477,7 +7478,7 @@ img { max-width: 100%; display: block; } } .changelog-item li::before { - content: "•"; + content: "\2022"; position: absolute; left: 0; color: var(--accent-3); diff --git a/frontend/src/components/HomeClient.tsx b/frontend/src/components/HomeClient.tsx index e5ccc81..c10abb7 100644 --- a/frontend/src/components/HomeClient.tsx +++ b/frontend/src/components/HomeClient.tsx @@ -101,6 +101,7 @@ export default function HomeClient(props: Props) { { threshold: 0.1, rootMargin: "0px 0px -50px 0px" } ); + let scheduled = 0; const observeAll = () => { document.querySelectorAll(".reveal:not(.visible)").forEach((el, i) => { (el as HTMLElement).style.transitionDelay = `${(i % 6) * 0.1}s`; @@ -108,12 +109,21 @@ export default function HomeClient(props: Props) { }); }; + const schedule = () => { + if (scheduled) return; + scheduled = window.setTimeout(() => { + scheduled = 0; + observeAll(); + }, 80); + }; + observeAll(); - const mo = new MutationObserver(observeAll); + const mo = new MutationObserver(schedule); mo.observe(document.body, { childList: true, subtree: true }); return () => { observer.disconnect(); mo.disconnect(); + if (scheduled) clearTimeout(scheduled); }; }, []); diff --git a/frontend/src/components/Loader.tsx b/frontend/src/components/Loader.tsx index 8c4954f..b22f685 100644 --- a/frontend/src/components/Loader.tsx +++ b/frontend/src/components/Loader.tsx @@ -1,18 +1,27 @@ "use client"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; export default function Loader() { + const [done, setDone] = useState(false); + useEffect(() => { - const loader = document.getElementById("loader"); - const hide = () => loader?.classList.add("hidden"); - window.addEventListener("load", () => setTimeout(hide, 1800)); - const t = setTimeout(hide, 3000); - return () => clearTimeout(t); + const hide = () => setDone(true); + const onLoad = () => setTimeout(hide, 900); + if (document.readyState === "complete") { + const t = setTimeout(hide, 900); + return () => clearTimeout(t); + } + window.addEventListener("load", onLoad); + const fallback = setTimeout(hide, 2200); + return () => { + window.removeEventListener("load", onLoad); + clearTimeout(fallback); + }; }, []); return ( -
+