diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-02-24 02:18:20 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-02-26 02:21:41 +0800 |
commit | 046c71c4c282b7c9dce781c8a1f31c68a1515854 (patch) | |
tree | 48e72e89b22c569d716bf66e746ed4a8a0fbfd98 /www/assets/color-scheme.ts | |
parent | 471cacdd706002df81f5bee03729b8fca6c98f37 (diff) | |
download | crupest-046c71c4c282b7c9dce781c8a1f31c68a1515854.tar.gz crupest-046c71c4c282b7c9dce781c8a1f31c68a1515854.tar.bz2 crupest-046c71c4c282b7c9dce781c8a1f31c68a1515854.zip |
feat(www): YEAH!
Diffstat (limited to 'www/assets/color-scheme.ts')
-rw-r--r-- | www/assets/color-scheme.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/www/assets/color-scheme.ts b/www/assets/color-scheme.ts new file mode 100644 index 0000000..62a1b5c --- /dev/null +++ b/www/assets/color-scheme.ts @@ -0,0 +1,90 @@ +const key = "color-scheme" + +type scheme = "dark" | "light" | null + +function createResetTimer(cleanup: () => void, timeout = 1) { + let tag = 0 + return () => { + clearTimeout(tag) + tag = setTimeout(() => { + cleanup() + }, timeout * 1000) + } +} + +let current = localStorage.getItem(key) as scheme + +let inited = false + +function createToast(duration: number = 1): (text: string) => void { + const toast = document.createElement("div") + toast.className = "toast" + + const reset = createResetTimer(() => { + toast.remove() + }, duration) + + return (text) => { + if (!toast.isConnected) { + document.body.appendChild(toast) + } + toast.textContent = text + reset() + } +} + +const themeToast = createToast() + +function setTheme(value: scheme) { + let message = "" + current = value + + if (value == null) { + const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)").matches + value = prefersDarkScheme ? "dark" : "light" + message = `theme: system(${value})` + localStorage.removeItem(key) + } else { + message = `theme: force(${value})` + localStorage.setItem(key, value) + } + + document.body.dataset["theme"] = value + + if (inited) { + themeToast(message) + } +} + +setTheme(current) +inited = true + +function next(scheme: scheme): scheme { + switch (scheme) { + case "dark": + return "light" + case "light": + return null + default: + return "dark" + } +} + +window.addEventListener("load", () => { + const slogon = document.getElementById("slogan")! + let clicks: number = 0 + + const reset = createResetTimer(() => { + clicks = 0 + }) + + slogon.addEventListener("click", () => { + reset() + clicks += 1 + if (clicks === 3) { + setTheme(next(current)) + clicks = 0 + } + }) +}) + |