Skip to content

refactor(tray): extract Settings page into a WinUI-free view model over a settings store#1043

Open
bkudiess wants to merge 1 commit into
mainfrom
bkudiess-mvvm-pilot-settings-permissions
Open

refactor(tray): extract Settings page into a WinUI-free view model over a settings store#1043
bkudiess wants to merge 1 commit into
mainfrom
bkudiess-mvvm-pilot-settings-permissions

Conversation

@bkudiess

Copy link
Copy Markdown
Collaborator

Moves the Settings page's settings read/persist logic out of the code-behind into a WinUI-free view model backed by a new settings facade, as a behavior-and-visual-identical refactor. First page to adopt the merged DI + navigation activation seam and the first visible reduction of a page god-file.

What changed

  • Add ISettingsStore (SettingsStore): immutable snapshot read, batched Update, a single non-echoing Changed (self-originated saves suppressed; external saves marshaled to the UI thread), and BeginSelfWrite() so App-owned direct writes (auto-start OS registration, speaker mute from Settings) share the same echo suppression.
  • Add SettingsPageViewModel (WinUI-free): two-way-bindable settings state that persists through the store, preserving the save/notify contract and the read-aloud / tool-call side effects, reloading on external change without re-persisting, and normalizing combo values so a legacy tag never renders blank.
  • Add SettingsAppInfoProjection (WinUI-free) for the About section strings.
  • Bind SettingsPage.xaml to the view model; shrink the code-behind (about -258 lines) to the remaining view concerns (gateway removal dialog, uptime timer, saved indicator, app-info, gateway-section refresh on external change).
  • Populate the page to view-model map so the navigation hook resolves and binds the view model; add ApplyAutoStart / SetChatSpeakerMuted / SetChatToolCallsVisible to the app-commands adapter, with mute suppression scoped to the Settings-originated call so a mute toggled elsewhere still refreshes an open Settings page.
  • Record settings-store and settings-page-vm in the architecture ledger with behavioral guard tests.

Validation

  • ./build.ps1
  • dotnet test tests/OpenClaw.Shared.Tests (3170 passed)
  • dotnet test tests/OpenClaw.Tray.Tests (1954 passed)

New tests cover the store (self-write suppression, external-change echo, depth reset), the view model (field mapping, save/notify ordering, no-echo, combo normalization, auto-start success/failure), and the app-info projection; ledger consistency passes.

Real behavior proof

Isolated build: navigated to Settings via the node app.navigate command; toggles and combos persist to settings.json and flash the Saved indicator; a legacy value renders the correct item instead of a blank combo; Start-with-Windows persists through the ordered auto-start path and shows Saved only after it persists; the About section renders the runtime/version/channel/build-date projection; values survive an app restart with no spurious save on open. Renders identically to the pre-change page.

…er a settings store

Moves the Settings page's settings read/persist logic out of the code-behind
into a WinUI-free view model backed by a new settings facade, as a
behavior-and-visual-identical refactor. First page to adopt the merged DI +
navigation activation seam and the first visible reduction of a page god-file.

- Add ISettingsStore (SettingsStore): immutable snapshot read, batched Update, a
  single non-echoing Changed (self-originated saves suppressed; external saves
  marshaled to the UI thread), and BeginSelfWrite() so App-owned direct writes
  share the same echo suppression.
- Add SettingsPageViewModel (WinUI-free): two-way-bindable settings state that
  persists through the store, preserving the save/notify contract and the
  read-aloud / tool-call side effects, reloading on external change without
  re-persisting, and normalizing combo values so a legacy tag never renders blank.
- Add SettingsAppInfoProjection (WinUI-free) for the About section strings.
- Bind SettingsPage.xaml to the view model; shrink the code-behind to the
  remaining view concerns (gateway removal dialog, uptime timer, saved indicator,
  app-info, gateway-section refresh on external change).
- Populate the page->view-model map so the navigation hook resolves and binds the
  view model; add ApplyAutoStart/SetChatSpeakerMuted/SetChatToolCallsVisible to
  the app-commands adapter, with mute suppression scoped to the Settings call.
- Record settings-store and settings-page-vm in the architecture ledger with
  behavioral guard tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown

ClawSweeper status: review started.

I am starting a fresh review of this pull request: refactor(tray): extract Settings page into a WinUI-free view model over a settings store This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

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.

1 participant