Skip to content

Pick Light, Dark or Follow system from Settings - #237

Merged
henriqueaklein merged 6 commits into
developfrom
feat/appearance-control
Sep 22, 2026
Merged

henriqueaklein merged 6 commits into
developfrom
feat/appearance-control

Conversation

@braianxde

Copy link
Copy Markdown
Contributor

Until now there was no way to change the app's appearance on a normal build. The only
light/dark toggles lived behind the dev-tools define, so a shipped wallet was stuck with
whatever the OS happened to be on first launch, with no override.

What changed

  • Settings has an Appearance control at the top of the page: Light, Dark, or
    Follow system.
  • Choosing one re-skins the app immediately, on the screen you're already looking at —
    you don't have to navigate away and back.
  • Follow system now tracks the OS while the app is running. Change Windows' app mode
    and the wallet follows, with no relaunch. That behaviour did not exist before in any form.
  • Anyone who already had light or dark saved keeps it, untouched.
  • A first launch with no saved preference still follows the OS, exactly as it did before.

This also unblocks something: three plans carry a "re-skins live on an in-place appearance
toggle" check that could never actually be run, because reaching the dev toggle forced a
navigation and that rebuild hid the very staleness the check exists to catch. That check is
now runnable from Settings on any build.

Verification

1555 tests pass / 5 skipped / 0 failing (5 new, against a 1550 baseline); analyzer clean;
format, brace, raw-colour, seed-safety, key-logging and agent-rules gates all pass. Walked
on a real Windows debug build: all three options, the in-place re-skin, the live OS flip,
and persistence across a relaunch.

Deliberately not here

Status pills and disabled checkboxes still fail contrast in light mode — those are fixed on
a separate branch, not folded in here.

The dev sun/moon toggles stay as they are; they now share one mechanism with this control
rather than being the only way in.

The todo about const widgets not re-skinning stays open. Its named widgets were fixed, but
it still tracks the deferred colour readers, so closing it here would claim more than this
change earns.

@braianxde
braianxde marked this pull request as ready for review September 22, 2026 13:03
@henriqueaklein

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-22T15:28:07.232201Z 89d6ebe Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 035ee6290a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread test/theme/gw_appearance_preference_test.dart Outdated
Comment thread lib/theme/gw_appearance.dart
Comment thread lib/settings/settings_screen.dart
@braianxde

Copy link
Copy Markdown
Contributor Author

One more from a separate review pass, not caught above — recording it rather than fixing it, since it's dev-only.

setMode() now silently overwrites a "Follow system" choice. It delegates to setPreference and always resolves to an explicit light/dark, so a developer who picks Follow system in Settings and then taps the dev-tools bubble or the gallery sun/moon has their preference overwritten and persisted. Before this PR setMode only moved the painted mode, so there was no preference to lose.

Compile-gated out of release builds by kDebugMode && kShowDevTools, so no user sees it. It only bites a developer exercising both surfaces in one session, who would then wonder why Follow system stopped following. Worth knowing rather than worth a fix.

Two CI notes for whoever picks this up:

@henriqueaklein

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89d6ebe036

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/settings/settings_screen.dart
… flips

- Add GWAppearancePreference (system/light/dark) split from the resolved GWAppearanceMode
- load()/setPreference() persist and resolve against OS brightness; setMode() delegates
- settings_screen.dart gets an Appearance card (_AppearanceControl on GWSelect) as its first section
- 5 cases: light/system load, setPreference round-trip, system-preference OS flip, light-preference OS flip left alone
- Only the OS-flip-while-system case fails: no WidgetsBindingObserver exists yet
- GWAppearance mixes in WidgetsBindingObserver; didChangePlatformBrightness re-resolves only while preference is system
- Observer registered from load() behind an _observing guard so a second load() (dev token probe) never double-registers
- dispose() removes the observer before super.dispose() for test teardown
- Appearance card on /settings closes the verification blocker; its recipe no longer needs the dev Gallery
- git mv to todos/completed/; the const-staleness sibling todo stays open with a dated note
A write that throws left the app in the old appearance with no way back:
the guard at the top of setPreference had already taken the new value, so
asking for it again returned immediately. Applying the mode first costs a
failed write only the next launch.

Also brings the quick-task artifacts inside their budgets and drops two
test-file names from a source comment.
@braianxde
braianxde force-pushed the feat/appearance-control branch from 89d6ebe to 387e4f4 Compare September 22, 2026 15:50
@henriqueaklein
henriqueaklein merged commit 667a5cf into develop Sep 22, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants