diff options
Diffstat (limited to 'source/js/script.ts')
-rw-r--r-- | source/js/script.ts | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/source/js/script.ts b/source/js/script.ts index bfc1d64..f184f2c 100644 --- a/source/js/script.ts +++ b/source/js/script.ts @@ -17,7 +17,7 @@ window.addEventListener("load", () => { } // Add header hover page class changer - const colorman = (mode: SystemDarkmodePreference) => { + const colorman = (mode: SystemDarkmodePreference | null) => { let clsname: string = ".auto-dark"; const elements: Element[] = Array.prototype.slice.call( document.querySelectorAll(clsname), 0); @@ -31,12 +31,12 @@ window.addEventListener("load", () => { element?.classList.remove("is-dark"); } }) - console.debug(`${clsname} class changed to ${enumModeToStringMode(mode)}`); + console.debug(`${clsname} class changed to ${enumModeToStringMode(mode) ? enumModeToStringMode(mode) : "light since mode == null"}`); } darklistener.add(colorman); // Add logo color selector - const logoman = (mode: SystemDarkmodePreference) => { + const logoman = (mode: SystemDarkmodePreference | null) => { const logo = document.getElementById("logo"); const darksrc = logo?.getAttribute("data-src-darkmode"); const lightsrc = logo?.getAttribute("data-src-lightmode"); @@ -44,12 +44,12 @@ window.addEventListener("load", () => { return; let src = (mode === SystemDarkmodePreference.dark) ? darksrc : lightsrc; logo.setAttribute("src", src); - console.debug(`logo src changed to ${enumModeToStringMode(mode)}src`); + console.debug(`logo src changed to ${enumModeToStringMode(mode) ? enumModeToStringMode(mode) : "light since mode == null"}`); } darklistener.add(logoman); // Add player theme handler - const playerman = (mode: SystemDarkmodePreference) => { + const playerman = (mode: SystemDarkmodePreference | null) => { const shikwasa = document.body.querySelector('div[data-name="shikwasa"]'); shikwasa?.setAttribute("data-theme", enumModeToStringMode(mode) ? enumModeToStringMode(mode)! : "light"); console.debug(`shikwasa theme: ${shikwasa?.getAttribute("data-theme")}`); @@ -76,23 +76,32 @@ const invertDarkModeObj: Object = { 'light': 'dark' }; -const enumModeToStringMode = (i: SystemDarkmodePreference) => { +const enumModeToStringMode = (i: SystemDarkmodePreference | null) => { let keysArray = Object.keys(modeMap); let result = keysArray.filter(key => isValidKey(key, modeMap) && modeMap[key] === i); return result ? result[0] : undefined; }; class DarkmodeListener { - private _mode: SystemDarkmodePreference; + private _mode: SystemDarkmodePreference | null; private _handlers: ((mode: SystemDarkmodePreference) => void)[]; public constructor() { let darking = window.matchMedia('(prefers-color-scheme: dark)').matches; - this._mode = darking ? SystemDarkmodePreference.dark : SystemDarkmodePreference.light; + this._mode = darking ? SystemDarkmodePreference.dark : null; this._handlers = []; } public listen(): void { + let media = window.matchMedia('(prefers-color-scheme: dark)'); + let callback = (event: MediaQueryListEvent) => { + let mode = event.matches ? SystemDarkmodePreference.dark : null; + applyCustomDarkModeSettings(mode); + setLS(darkModeStorageKey, enumModeToStringMode(mode!)); + this._mode = mode; + }; + media.addEventListener("change", callback); + const rootElement = document.documentElement; const darkModeStorageKey = 'user-color-scheme'; const rootElementDarkModeAttributeName = 'data-user-color-scheme'; @@ -104,17 +113,26 @@ class DarkmodeListener { } // Partially taken from https://blog.skk.moe/post/hello-darkmode-my-old-friend, CC BY-NC-SA 4.0 - const applyCustomDarkModeSettings = (mode: any) => { + const applyCustomDarkModeSettings = (mode: SystemDarkmodePreference | null) => { // 接受从「开关」处传来的模式,或者从 localStorage 读取 - let LSSetting = getLS(darkModeStorageKey) == 'dark' ? SystemDarkmodePreference.dark : 'light' ? SystemDarkmodePreference.light : null; - let currentSetting: SystemDarkmodePreference = mode || LSSetting; + let LSSetting = getLS(darkModeStorageKey) == 'dark' ? SystemDarkmodePreference.dark : getLS(darkModeStorageKey) == 'light' ? SystemDarkmodePreference.light : null; + console.debug(`Got LSSetting: ${LSSetting}; mode: ${mode}`); + // 如果传入 mode != null (浏览器设置了prefers-color-scheme: dark)且 LocalStorage为空,则使用传入模式 + let currentSetting: SystemDarkmodePreference | null; + if (mode != null && LSSetting == null) { + currentSetting = mode; + } else { + // 否则,使用 localStorage 中的设置(可能为 null!) + currentSetting = LSSetting; + } console.debug(`applyCustomDarkModeSettings: ${currentSetting}`); - if (currentSetting === this._mode) { + let prefersColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? SystemDarkmodePreference.dark : null; + if (currentSetting == prefersColorScheme && currentSetting != null) { // 当用户自定义的显示模式和 prefers-color-scheme 相同时重置、恢复到自动模式 resetRootDarkModeAttributeAndLS(); console.debug('Resetting to auto mode...'); } else if (currentSetting == SystemDarkmodePreference.dark || currentSetting == SystemDarkmodePreference.light) { - // 否则设置为用户自定义的显示模式 + // 否则设置为用户自定义的显示模式或传入的模式 rootElement.setAttribute(rootElementDarkModeAttributeName, enumModeToStringMode(currentSetting)!); console.debug('Setting prop: "data-user-color-scheme" in HTML...'); } else { @@ -146,12 +164,14 @@ class DarkmodeListener { }); console.debug('Light theme applied.'); } - + // 更新 this._mode + this._mode = currentSetting; } const toggleCustomDarkMode = () => { let currentSetting = getLS(darkModeStorageKey); if (currentSetting === null) { + // localStorage 啥都没有,从this._mode获取 let curMode = enumModeToStringMode(this._mode)!; currentSetting = isValidKey(curMode, invertDarkModeObj) ? invertDarkModeObj[curMode] : currentSetting; } else if (currentSetting == 'dark' || 'light') { @@ -163,24 +183,26 @@ class DarkmodeListener { } // 将相反的模式写入 localStorage setLS(darkModeStorageKey, currentSetting); - return isValidKey(currentSetting!, invertDarkModeObj) ? modeMap[currentSetting!] : null; + // 更新 DarkmodeListener._mode + this._mode = isValidKey(currentSetting!, modeMap) ? modeMap[currentSetting!] : this._mode; } - applyCustomDarkModeSettings(null); + applyCustomDarkModeSettings(this._mode); darkModeTogglebuttonElement?.addEventListener('click', () => { // 当用户点击「开关」时,获得新的显示模式、写入 localStorage、并在页面上生效 console.debug('User clicked button. Doing black magic now...'); - applyCustomDarkModeSettings(toggleCustomDarkMode()); + toggleCustomDarkMode(); + applyCustomDarkModeSettings(this._mode); }); } - public add(callback: (mode: SystemDarkmodePreference) => void): void { + public add(callback: (mode: SystemDarkmodePreference | null) => void): void { callback(this._mode); this._handlers.push(callback); } - public mode(): SystemDarkmodePreference { + public mode(): SystemDarkmodePreference | null { return this._mode; } }; |