Repository navigation
Read the settings before the first render, so a custom theme is painted from the app's first render - #651
Merged
Conversation
…ed from the app's first render The follow-up of #650. The settings were read once the app had mounted, and the theme is one of them, so a custom theme was painted after a first render in the standard theme of its scheme: a flash of the wrong colours at every launch. The window reads the settings beside the locale now, before its first render, and hands them to the hook that holds them; a read that fails leaves the hook to ask again once mounted, as it did. No new bridge surface: the same ask, made earlier. What the page paints before its script runs, the stylesheet's light surface or the dark seed, is as it was. The custom theme journey reloads the page with a script in it before any of its own, which notes the document's own style at the moment the app mounts, before the app's first frame is painted: the custom colours, not the standard theme's and not none. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ryanwelcher
added a commit
that referenced
this pull request
Oct 13, 2026
## Why 41 commits have reached trunk since `v1.2.1`, and milestone `v2.0.0-beta.1` has 77 closed issues and none open. The main changes are the redesign on the WordPress Design System (#591), a settings dialog with language, theme, PHP version and debug flags (#638 to #651), and translation of the whole interface (#634 to #664). This is a beta: it ships with `--prerelease`, so `releases/latest` stays on `v1.2.1`. `electron-builder` names the artifacts after `package.json`, so the version has to move before the tag and artifacts exist. ## What changes - **The version.** The three root version fields in `package.json` and `package-lock.json` move from `1.2.1` to `2.0.0-beta.1`. No dependency versions change. - **The first shipped translations.** `npm run i18n:download` added a catalog for each of the seven locales at 80% or more on translate.wordpress.org. None was removed, and no right-to-left locale was held back. | Locale | Translated | Strings | | --- | --- | --- | | cs | 94% | 1001 | | en-ca | 100% | 1062 | | en-gb | 100% | 1062 | | gl | 100% | 1062 | | hu | 100% | 1062 | | nl | 100% | 1062 | | pl | 96% | 1028 | ## How to test this **Platforms:** any for steps 1 to 3. The artifact checks need macOS for `Info.plist` and Windows for the `.exe`. **Starting state:** this branch checked out with `node_modules` installed. Run every command from the repository root. 1. `npm run lint` is clean and `npm test` passes. 2. `node -e "console.log(require('./package.json').version)"` prints `2.0.0-beta.1`. 3. `python3 -c "import json;d=json.load(open('package-lock.json'));print(d['version'], d['packages']['']['version'])"` prints `2.0.0-beta.1 2.0.0-beta.1`. 4. On the Buildkite build for the current head, the artifacts are named `wordpress-contributor-toolkit-2.0.0-beta.1-*`. The `app.asar` root holds exactly `node_modules`, `package.json` and `src`, with npm 11 under `node_modules/npm` and no `.codesigning`. On macOS, `CFBundleShortVersionString` reads `2.0.0-beta.1`. 5. In the installed app, set the language to Dutch in the settings and relaunch. The interface is in Dutch. **What must not have happened:** no dependency version may change. `git diff trunk -- . ':!src/languages'` shows exactly three changed lines, all of them the root version. ## Risks and limitations `npm test` run from an interactive terminal fails two integration tests on macOS. That is a test bug, fixed separately in #680. It does not affect CI or the app. ## Related Milestone `v2.0.0-beta.1`. Release notes follow on the release. --- <details> <summary>Review outcome (required — see AGENTS.md)</summary> 0 [fix here] · 0 [follow-up]. Automatic checks only, as in #533: this change has no logic to review. - **Review:** completed, deterministic layer, in session; head `9853082` / base `5d5f701` (trunk). `npm run lint` passes, `npm test` passes (2098 tests, 0 failures, 2 skipped), both files are valid JSON, and the diff outside `src/languages/` is the three root version fields. Outcome: nothing to fix. - **Since review:** none. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The follow-up recorded in #650: a custom theme was painted after a first render in the standard theme of its scheme, a flash of the wrong colours at every launch, because the settings, of which the theme is one, were read in an effect once the app had mounted. Part of #560.
What changes
The settings are read before the first render, beside the locale, which the window already waited for; the two reads run together, so the first paint waits for neither longer than before. What was read is handed to the hook that holds the settings, which asks main again only where that read failed, as it did before. No new bridge surface: the same ask, made earlier.
What remains: before the page's script runs at all, the page paints the stylesheet's light surface, or under the dark scheme the dark seed
index.htmlpaints, over a window frame that is already the custom colour; a custom theme shows that for that moment, then its own colours. The review's idea of a transparent body until the provider mounts, so the frame shows through, was tried and measured: in the light scheme the window's colour did show through, but under the dark scheme Chromium paints its own canvas colour,#121212, over the frame, so a custom dark theme would still flash, and the standard dark theme would flash a grey that is not its seed. Not taken. The page cannot know its colour before its script runs without being handed it, which is new bridge surface.Mail rendering is unchanged here and tracked separately.
How to test this
Platforms: any. The journeys drive this on macOS and Windows. From the repository root, after
npm ciandnpm run build:once:settings.spec.js, the custom theme journey, at its end: the page is reloaded with a script in it before any of its own, which notes the document's own style at the moment the app mounts, before anything is painted; the custom colours are in it, and not the standard theme's, and not none. On the code before this change the journey receives an empty style there, since a custom light theme's first render was the standard light theme, which puts nothing on the document.Nothing else is new to test: the settings dialog's journeys and the language relaunch cover the hook as it is handed the settings.
Worth a look by hand (any platform, the current head): Settings → General → Theme → Custom, a background such as
fff8e1, quit, open the app: the window is cream from the app's first render, with no moment of the standard light theme after the page has mounted. With102030: navy from the app's first render; what the page paints before its script runs is the dark seed.What must not have happened: the app failing to open its window when the settings cannot be read (the read's failure is logged and the hook asks again); a slower first paint; the language relaunch offer appearing on a fresh launch.
What I could not test: the packaged smoke on this head, since my own copy of the app held the single-instance lock; the change is the renderer's and the bridge is unchanged.
Risks and limitations
Related
Follow-up of #650, part of #560 and #542.
Review outcome (required — see AGENTS.md)
Pass 1: 1 [fix here] · 1 [follow-up] · 0 style notes. Pass 2 (on the fix-up): 0 [fix here] · 0 [follow-up] · 2 style notes. The finding fixed here, the follow-up tried and not taken, both style notes applied.
c3801dd/ basee0ed3ee; the hook's seeding against the language relaunch'sloaded, the two reads' failure paths and timing, the reload against the deep-link queue and the provider's root count, the observer's timing against React's commit, the journey red on the old code; ESLint and the unit files run; 1 [fix here], 1 [follow-up].d434c55/ basee0ed3ee; the wording checked place by place, the observer's timing against the provider's layout effect; ESLint and the unit files run; 0 findings, 2 style notes.d434c55. On the tree:npm run lint,npm test,npm run test:electron(2045), all 133 journeys and the docs build pass; the packaged smoke could not run, since the maintainer's own app holds the single-instance lock, and the bridge is unchanged.Implementation notes
src/renderer/index.jsx:loadSettings,Root({ initialSettings }), the two reads before the first render.src/renderer/hooks/use-settings.jsx:useSettings(initial).src/renderer/components/app-theme.jsx: the comment.tests/e2e/journeys/settings.spec.js: the reload with the mount observer.Screenshots or recording
Not attached: what changed is the first frame, which a picture taken later does not show. The journey reads it.
🤖 Generated with Claude Code