diff options
Diffstat (limited to 'web/script/transition.ts')
| -rw-r--r-- | web/script/transition.ts | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/web/script/transition.ts b/web/script/transition.ts deleted file mode 100644 index dadb266..0000000 --- a/web/script/transition.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - This file is part of jellything (https://codeberg.org/metamuffin/jellything) - which is licensed under the GNU Affero General Public License (version 3); see /COPYING. - Copyright (C) 2026 metamuffin <metamuffin.org> -*/ -/// <reference lib="dom" /> - -import { e } from "./jshelper/src/element.ts"; - -interface HistoryState { - top: number -} - -const DURATION = 200 -globalThis.addEventListener("DOMContentLoaded", () => { - patch_page() -}) - -globalThis.addEventListener("popstate", async e => { - await transition_to(globalThis.location.href, e.state) -}) - -let disable_transition = false -globalThis.addEventListener("navigationrequiresreload", () => { - disable_transition = true -}) - -function patch_page() { - document.querySelectorAll("a").forEach(el => { - if (!el.href.startsWith("http")) return - if (el.target && el.target != "_self") return - el.addEventListener("click", async ev => { - ev.preventDefault() - await transition_to(el.href) - }) - }) -} - -async function transition_to(href: string, state?: HistoryState) { - stop() // nice! - if (disable_transition) return globalThis.location.href = href - const trigger_load = prepare_load(href, state) - await fade(false) - trigger_load() - disable_transition = false; -} - -function show_message(mesg: string, mode: "error" | "success" = "error") { - clear_spinner() - disable_transition = true - document.body.append(e("span", { class: ["jst-message", mode] }, mesg)) -} - -let i = 0; -function prepare_load(href: string, state?: HistoryState) { - const r_promise = fetch(href, { headers: { accept: "text/html" }, redirect: "manual" }) - return async () => { - let rt = "" - try { - const r = await r_promise - if (r.type == "opaqueredirect") { - globalThis.location.href = href - show_message("Native Player Started.", "success") - setTimeout(() => globalThis.location.reload(), 500) - return - } - if (!r.ok) return show_message("Error response. Try again.") - rt = await r.text() - } catch (e) { - if (e instanceof TypeError) return show_message("Navigation failed. Check your connection.") - return show_message("unknown error when fetching page") - } - const [head, body] = rt.split("<head>")[1].split("</head>") - globalThis.history.replaceState({ top: globalThis.scrollY, index: i++ } as HistoryState, "") - if (!state) globalThis.history.pushState({}, "", href) - clear_spinner() - document.head.innerHTML = head - document.body.outerHTML = body - globalThis.dispatchEvent(new Event("DOMContentLoaded")) - globalThis.scrollTo({ top: state?.top ?? 0 }); - fade(true) - } -} - -let spinner_timeout: number | undefined, spinner_element: HTMLElement | undefined; -function clear_spinner() { - if (spinner_timeout) clearTimeout(spinner_timeout) - if (spinner_element) spinner_element.remove() - spinner_element = spinner_timeout = undefined; -} -function fade(dir: boolean) { - const overlay = document.createElement("div") - overlay.classList.add("jst-fade") - overlay.style.backgroundColor = dir ? "black" : "transparent" - overlay.style.animationName = dir ? "jst-fadeout" : "jst-fadein" - overlay.style.animationFillMode = "forwards" - overlay.style.animationDuration = `${DURATION}ms` - document.body.appendChild(overlay) - return new Promise<void>(res => { - setTimeout(() => { - if (dir) document.body.removeChild(overlay) - spinner_timeout = setTimeout(() => { - overlay.append(spinner_element = e("div", { class: "jst-spinner" }, "This is a spinner.")) - }, 500) - res() - }, DURATION) - }) -} |