Conversation
- Applies dark theme immediately at `document-start` using `data-bs-theme` and critical preloader CSS to prevent flash of unstyled/light content. - Leverages localStorage via `UtilityEnabled` for reliable early theme detection. - Enhances user experience with smoother theme transition on page load.
Added a `color-scheme` meta tag to improve browser UI hints for dark/light modes and updated the dark mode preloader to temporarily hide the body, preventing visual flashes during Bootstrap transitions. Also streamlined style cleanup on DOMContentLoaded for better consistency.
8fff998 to
3cad8b4
Compare
|
@langningchen this |
There was a problem hiding this comment.
Pull Request Overview
This PR fixes page flashes in dark mode by applying a minimal dark-theme preload at document-start, then removing it once the page loads.
- Bumps version to 1.6.1 and registers the release in
Update.json. - Adds
@run-at document-start,UtilityEnabled, andapplyInitialThemeinXMOJ.user.jsto inject and later remove dark-mode preload styles. - Adjusts error logging in
RequestAPIfromconsole.errortoconsole.log.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| package.json | Updated version to 1.6.1 |
| XMOJ.user.js | Added @run-at document-start; implemented UtilityEnabled and applyInitialTheme; removed stale utility; adjusted logging and style removal on load. |
| Update.json | Added entry for version 1.6.1 with update metadata |
Comments suppressed due to low confidence (3)
XMOJ.user.js:42
- [nitpick] The function name UtilityEnabled is ambiguous and doesn’t follow common JS boolean naming conventions. Consider renaming it to isUtilityEnabled or hasUtilityEnabled to clarify that it returns a boolean.
let UtilityEnabled = (Name) => {
XMOJ.user.js:54
- There’s no automated coverage for applyInitialTheme’s logic (injection/removal of preload styles). Consider adding unit tests or integration tests to verify both dark and light paths.
const applyInitialTheme = () => {
XMOJ.user.js:523
- [nitpick] Swapping console.error for console.log downplays errors. It may be clearer to use console.warn (or leave console.error) so that parsing failures remain visible as errors.
console.log(Response.responseText);
| let UtilityEnabled = (Name) => { | ||
| try { | ||
| Input = new Date(Input); | ||
| let Now = new Date().getTime(); | ||
| let Delta = Now - Input.getTime(); | ||
| let RelativeName = ""; | ||
| if (Delta < 0) { | ||
| RelativeName = "未来"; | ||
| } else if (Delta <= 1000 * 60) { | ||
| RelativeName = "刚刚"; | ||
| } else if (Delta <= 1000 * 60 * 60) { | ||
| RelativeName = Math.floor((Now - Input) / 1000 / 60) + "分钟前"; | ||
| } else if (Delta <= 1000 * 60 * 60 * 24) { | ||
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60) + "小时前"; | ||
| } else if (Delta <= 1000 * 60 * 60 * 24 * 31) { | ||
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24) + "天前"; | ||
| } else if (Delta <= 1000 * 60 * 60 * 24 * 365) { | ||
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 31) + "个月前"; | ||
| } else { | ||
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 365) + "年前"; | ||
| if (localStorage.getItem("UserScript-Setting-" + Name) == null) { | ||
| const defaultOffItems = ["DebugMode", "SuperDebug", "ReplaceXM"]; | ||
| localStorage.setItem("UserScript-Setting-" + Name, defaultOffItems.includes(Name) ? "false" : "true"); | ||
| } | ||
| return "<span title=\"" + Input.toLocaleString() + "\">" + RelativeName + "</span>"; | ||
| return localStorage.getItem("UserScript-Setting-" + Name) == "true"; |
There was a problem hiding this comment.
The string "UserScript-Setting-" is repeated in multiple places. Extract it into a constant (e.g. STORAGE_KEY_PREFIX) to avoid duplication and typos.
| let UtilityEnabled = (Name) => { | |
| try { | |
| Input = new Date(Input); | |
| let Now = new Date().getTime(); | |
| let Delta = Now - Input.getTime(); | |
| let RelativeName = ""; | |
| if (Delta < 0) { | |
| RelativeName = "未来"; | |
| } else if (Delta <= 1000 * 60) { | |
| RelativeName = "刚刚"; | |
| } else if (Delta <= 1000 * 60 * 60) { | |
| RelativeName = Math.floor((Now - Input) / 1000 / 60) + "分钟前"; | |
| } else if (Delta <= 1000 * 60 * 60 * 24) { | |
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60) + "小时前"; | |
| } else if (Delta <= 1000 * 60 * 60 * 24 * 31) { | |
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24) + "天前"; | |
| } else if (Delta <= 1000 * 60 * 60 * 24 * 365) { | |
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 31) + "个月前"; | |
| } else { | |
| RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 365) + "年前"; | |
| if (localStorage.getItem("UserScript-Setting-" + Name) == null) { | |
| const defaultOffItems = ["DebugMode", "SuperDebug", "ReplaceXM"]; | |
| localStorage.setItem("UserScript-Setting-" + Name, defaultOffItems.includes(Name) ? "false" : "true"); | |
| } | |
| return "<span title=\"" + Input.toLocaleString() + "\">" + RelativeName + "</span>"; | |
| return localStorage.getItem("UserScript-Setting-" + Name) == "true"; | |
| const STORAGE_KEY_PREFIX = "UserScript-Setting-"; | |
| let UtilityEnabled = (Name) => { | |
| try { | |
| if (localStorage.getItem(STORAGE_KEY_PREFIX + Name) == null) { | |
| const defaultOffItems = ["DebugMode", "SuperDebug", "ReplaceXM"]; | |
| localStorage.setItem(STORAGE_KEY_PREFIX + Name, defaultOffItems.includes(Name) ? "false" : "true"); | |
| } | |
| return localStorage.getItem(STORAGE_KEY_PREFIX + Name) == "true"; |
| } catch (e) { | ||
| console.error(e); | ||
|
|
||
| const applyInitialTheme = () => { |
There was a problem hiding this comment.
add a brief JSDoc or inline comment describing applyInitialTheme’s behavior, side effects, and when it should run, to improve readability and maintainability.
|
|
||
| const applyInitialTheme = () => { | ||
| const isDarkMode = UtilityEnabled("DarkMode"); | ||
| console.log("Initial DarkMode check (document-start):", isDarkMode); |
There was a problem hiding this comment.
[nitpick] This log runs on every page load and could clutter the console in production. Consider gate-ing it behind a debug flag or removing it once verified.
| console.log("Initial DarkMode check (document-start):", isDarkMode); | |
| if (UtilityEnabled("DebugMode")) { | |
| console.log("Initial DarkMode check (document-start):", isDarkMode); | |
| } |
|
hhh this is hard |
|
The only thing we can control is when we remove these temporary styles |
|
所以我认为这个没有方法可以完美的修复它
…________________________________
From: Zhu Chenrui ***@***.***>
Sent: Monday, June 2, 2025 7:59
To: XMOJ-Script-dev/XMOJ-Script ***@***.***>
Cc: Langning Chen ***@***.***>; Mention ***@***.***>
Subject: Re: [XMOJ-Script-dev/XMOJ-Script] Fix page flashes in dark mode (PR #802)
[https://avatars.githubusercontent.com/u/85378277?s=20&v=4]boomzero left a comment (XMOJ-Script-dev/XMOJ-Script#802)<#802 (comment)>
The only thing we can control is when we remove these temporary styles
―
Reply to this email directly, view it on GitHub<#802 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ATPDVNB4PUNX7IER7VFCIW33BOHX3AVCNFSM6AAAAAB6LBTAISVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSMRYGE2TGMJXHA>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
|
是的… |
|
How about first forcing dark mode in bootstrap 3? |
|
The browser has to remember this |
|
So when we open other pages, even the initial render would be dark |
|
Turns out bootstrap 3 doesn't even support dark mode... |
|
先 merge 了… |
|
…… |
? |
Emm 等一会写这个
What does this PR aim to accomplish?:
Fix page flashes in dark mode
How does this PR accomplish the above?:
Somehow
By submitting this pull request, I confirm the following:
git rebase)