refactor(settings): regroup SettingsPage into 7 progressive-disclosure groups
Phase 9c follow-up. The 2309-line hand-rolled accordion is replaced with
seven SettingsGroup-wrapped top-level groups, each containing the
relevant existing sub-sections as nested SettingsGroups:
1. Audio — microphone (input device).
2. Vocabulary — terms & profiles, profiles & templates (legacy manager
moved in here so all profile / vocabulary state lives together).
3. Transcription — engine, format mode, model management, compute device,
language. Defaults to open to preserve the prior accordion's landing.
4. AI & Processing — post-processing toggles, AI Assistant tier and
model management, if-then implementation rules. AI Assistant and
if-then rules moved out of their original positions to sit alongside
the deterministic post-processing toggles.
5. Tasks & Rituals — rituals (incl. launch-at-login, kept bundled with
the existing Rituals UI block to avoid splitting that block), tasks
page (sparkline), nudges.
6. Output & Capture — read aloud (TTS, lazy-loaded on first open via the
new SettingsGroup `onopen` hook), capture & export.
7. Appearance & System — global hotkey, appearance (theme/zone/font/
locale), accessibility, about (engine status + diagnostics).
Deviations from Codex's 7-group spec:
- Launch-at-login stays inside the Rituals sub-group (was bundled there
in the existing markup; relocating would require splitting the
Rituals UI block, which is out of scope for this pass).
- Profiles & Templates legacy manager pulled into the Vocabulary group
rather than appearance/system.
Implementation notes:
- SettingsGroup gains an optional `onopen` callback prop, fired once on
the first closed→open transition. Used by Read aloud to lazy-load TTS
voices and by AI & Processing to refresh LLM status. Replaces the
former toggleAiSection / toggleReadAloudSection imperative handlers.
- The centralised openSection state is removed; each <details> manages
its own disclosure.
- Tokens are inherited from app.css; the prior global token darkening
(commit 2da0a5b) covers all section labels via the existing utility
classes — no per-component label-class swaps were added.
Search box deferred to a follow-up commit. Forcing `open=true` on
SettingsGroup based on a filter input would require either a controlled
`open` prop or a {#key} re-mount strategy, both of which add risk to
this restructure pass.
Tauri-bridged commands cannot be exercised in browser-only `npm run
dev`; structural verification done via npm build, npm check, and a
live dev server fetch of /settings. Real persistence smoke needs a
tauri dev session.
Verification:
- cargo fmt --check: pre-existing whitespace diffs in src-tauri/src/
live.rs and src-tauri/src/lib.rs only (untouched by this commit).
- cargo clippy --all-targets -- -D warnings: clean.
- cargo test: 283 tests pass.
- npm run check: 1 pre-existing error in vite.config.js:5; 0 new.
- npm run build: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,13 +10,27 @@
|
||||
title: string;
|
||||
description?: string;
|
||||
open?: boolean;
|
||||
onopen?: () => void;
|
||||
children?: import("svelte").Snippet;
|
||||
}
|
||||
|
||||
let { title, description = "", open = false, children }: Props = $props();
|
||||
let { title, description = "", open = false, onopen, children }: Props = $props();
|
||||
|
||||
// Fires once on the first transition from closed → open. Used by
|
||||
// sections that lazy-load expensive data (e.g. TTS voice enumeration).
|
||||
// Plain let (not $state) — the flag is mutated only by the toggle
|
||||
// handler and never has to be reactive in the template.
|
||||
let hasOpened = false;
|
||||
function handleToggle(event: Event) {
|
||||
const el = event.currentTarget as HTMLDetailsElement | null;
|
||||
if (el?.open && !hasOpened) {
|
||||
hasOpened = true;
|
||||
onopen?.();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<details {open} class="settings-group border-t border-border-subtle">
|
||||
<details {open} ontoggle={handleToggle} class="settings-group border-t border-border-subtle">
|
||||
<summary
|
||||
class="flex items-start gap-2 cursor-pointer list-none py-3 px-1 rounded hover:bg-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent"
|
||||
>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user