Skip to content

feat(settings): light mode toggle + manual update check - #24

Merged
Nic-dorman merged 2 commits into
mainfrom
feat/settings-appearance-and-updates
Apr 16, 2026
Merged

feat(settings): light mode toggle + manual update check#24
Nic-dorman merged 2 commits into
mainfrom
feat/settings-appearance-and-updates

Conversation

@Nic-dorman

@Nic-dorman Nic-dorman commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Rebased onto main (32e7a94, post PR #22 merge). Closes two TODO-list items from MEMORY.md, plus a small robustness fix.

Summary

1. Appearance — Light Mode toggle

  • New toggle in Settings flips dark ↔ light at runtime
  • autonomi-* Tailwind tokens now resolve through CSS custom properties; dark is the fallback (no light class on <html>), light-mode values live in assets/css/main.css under :root.light
  • Zero changes to component markup — every existing bg-autonomi-dark, text-autonomi-text, etc. remaps at runtime
  • Preference persists via load_config / save_config (new theme_mode field, #[serde(default)] so existing configs upgrade cleanly)
  • Small useTheme composable keeps <html>.classList and AppKit's themeMode in sync

2. Software — Check for Updates

  • Settings now has a Software block with current version + "Check for Updates" button
  • Previously the updater only ran once on app.vue mount — long-running sessions never saw new releases
  • updaterStore.checkForUpdate() now tracks checking / lastCheckedAt, returns a CheckResult so the button can toast "Update available", "You're on the latest version", or the error
  • Sidebar's existing "Update Available" button + the shared UpdateDialog keep working unchanged

3. Config robustness — retrofit #[serde(default)] across UploadHistoryEntry (second commit)

  • Only data_map_file had the attribute. Every other field (name, size_bytes, address, cost, uploaded_at) lacked it.
  • If a future field rename/removal or new required field is added without the attribute, the whole upload_history.json would fail to deserialize and user's history gets silently wiped on upgrade.
  • Applying the attribute to every field makes the struct fully forward-compatible. Missing fields parse as their type's default (empty String, 0, None) rather than erroring out the whole load.

Test plan

Automated:

  • npx nuxi typecheck — clean
  • npm run test:run — 19/19 passing
  • cargo check (src-tauri) — compiles clean

Manual (pre-merge):

  • Settings → toggle Light Mode: background / cards / text all flip; WalletConnect modal matches; reload persists the choice
  • Click Check for Updates — toast "You're on the latest version" on latest, "Update available" if stale
  • Upgrade an app that has an older upload_history.json (missing data_map_file) — history loads, rows show with empty datamap link

Notes

🤖 Generated with Claude Code

Nic-dorman and others added 2 commits April 16, 2026 20:04
Adds two Settings controls that were on the TODO list:

**Appearance — Light Mode toggle.** Theme-aware tokens (autonomi-dark /
surface / border / text / muted) are now resolved through CSS custom
properties. Dark values live in the Tailwind fallback so the default
palette is unchanged; adding `light` to <html> activates the overrides
defined in assets/css/main.css. Zero component markup changes — every
existing `bg-autonomi-dark`, `text-autonomi-text`, etc. remaps at
runtime. A small `useTheme` composable watches settings and keeps
<html>.classList and AppKit's themeMode in sync. The preference
persists via the existing load_config / save_config Tauri commands
(new `theme_mode` field on AppConfig, defaults to "dark" via
#[serde(default)] so existing config.toml files upgrade cleanly).

**Software — Check for Updates.** Previously the updater only ran
once on app launch, so long-running sessions never saw new releases.
Settings now has a Software block with the current app version and a
manual "Check for Updates" button that calls `updaterStore.check-
ForUpdate()` on demand. `checkForUpdate()` now tracks `checking` /
`lastCheckedAt` state and returns a CheckResult so callers can toast
appropriately ("Update available", "You're on the latest version",
or the error). The sidebar's existing "Update Available" button and
the shared UpdateDialog continue to work unchanged.

Known limitation: no visual browser test — UI logic is covered by
Nuxt typecheck, the Vitest suite (19/19), a full Nuxt prod build,
and `cargo check` for the Rust config change. First paint in light
mode will briefly show dark (until loadConfig resolves); acceptable
as a follow-up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only `data_map_file` previously had the attribute. If any of `name`,
`size_bytes`, `address`, `cost`, or `uploaded_at` is ever renamed,
removed, or migrates to a new required field, deserializing an older
`upload_history.json` would fail the whole file and silently wipe the
user's entire upload history on upgrade.

Applying #[serde(default)] to every field makes the struct fully
forward-compatible: missing fields in an on-disk entry now parse as
their type's default (empty String, 0, None) rather than erroring out
the whole load. Individual entries with missing required-feeling
fields will still look incomplete in the UI, but the rest of the
history survives, which is the right tradeoff for a user-facing log.
@Nic-dorman
Nic-dorman force-pushed the feat/settings-appearance-and-updates branch from 2083d86 to dac05b3 Compare April 16, 2026 19:07
@Nic-dorman
Nic-dorman merged commit d528861 into main Apr 16, 2026
4 checks passed
@Nic-dorman
Nic-dorman deleted the feat/settings-appearance-and-updates branch April 17, 2026 08:18
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