Skip to content

feat(desktop): settings + theme + command palette + better preview states#3

Closed
hqhq1025 wants to merge 2 commits intomainfrom
wt/preview-ux
Closed

feat(desktop): settings + theme + command palette + better preview states#3
hqhq1025 wants to merge 2 commits intomainfrom
wt/preview-ux

Conversation

@hqhq1025
Copy link
Copy Markdown
Collaborator

Summary

Reshapes the renderer so the app feels like a real product before any AI call returns. Strictly Tier 1 — no Radix, no react-hotkeys, no react-toastify, no framer-motion, no new prod deps. CSS animations and addEventListener only.

UX improvements

  • TopBar — app name + breadcrumb (Untitled / Generating… / Preview ready / Error) + 3 icon-buttons (command palette, theme toggle, settings) inside the macOS hiddenInset drag region.
  • Settings overlay — 4 tabs: Models (stub, key entry lands with wt/onboarding), Appearance (light/dark theme picker), Storage (shows ~/.config/open-codesign/config.toml), Advanced (placeholder).
  • Command paletteCmd+K opens; 4 actions (New Design, Toggle Theme, Open Settings, Export — Export is a stub toast); arrow-key + Enter navigation.
  • Theme toggle — single icon button, persists to localStorage. Inline <script> in index.html applies the .dark class before React mounts to avoid FOUC.
  • Toast notifications — Zustand-backed, auto-dismiss 4s, stack bottom-right; surface generation completion ("Design ready") and errors with description.
  • PreviewPane with three explicit states:
    • EmptyState — softer illustration + 3 starter chips that populate the prompt input.
    • LoadingState — pure-CSS shimmer skeleton.
    • ErrorState — friendly card with Retry + Copy Error + Dismiss.
  • Keyboard shortcutsCmd/Ctrl+Enter sends prompt, Cmd+, opens Settings, Cmd+K opens palette, Esc closes overlays. All wired through a single useKeyboard registry.
  • Sidebar extracted from App.tsx; App.tsx is now a thin composition of TopBar + Sidebar + PreviewPane + overlays.
  • UI primitives — new IconButton and pure-CSS Tooltip (400ms hover delay via transition-delay) in packages/ui.
  • Tokens — added --color-toast-success, --color-toast-error, --color-overlay for both light and dark palettes.

Compliance

  • No new prod deps. Only lucide-react (already a dep) is used for new icons.
  • No silent fallbacks. Every error path pushes a toast and surfaces in ErrorState.
  • Tokens only. No hex literals or new hardcoded px in changed files (rems used for the Settings panel sizing).
  • TypeScript strict — clean pnpm -r typecheck.
  • Lint — clean pnpm lint (Biome).
  • Testspnpm -r test green.
  • Worktree boundary respected — no edits to apps/desktop/src/main/**, preload/index.ts, renderer/src/onboarding/**, or any package owned by other worktrees.
  • DCO — both commits signed off.

Test plan

  • pnpm install && pnpm -r typecheck && pnpm lint && pnpm -r test green
  • pnpm --filter @open-codesign/desktop dev boots
  • Cmd+, opens Settings; Cmd+K opens palette; Cmd+Enter submits
  • Theme toggle in Settings → Appearance flips instantly; restart preserves choice without FOUC
  • EmptyState chips populate the prompt input on click
  • useCodesignStore.setState({ errorMessage: 'boom' }) shows ErrorState with Retry + Copy
  • Toast appears on simulated generation completion

haoqing added 2 commits April 18, 2026 12:21
- IconButton: compact square button for toolbar/topbar use, with focus
  ring and disabled state aligned to existing Button.
- Tooltip: pure-CSS tooltip with 400ms hover delay (no JS, no Radix).
- Tokens: add --color-toast-success, --color-toast-error, --color-overlay
  for both light and dark palettes.

Tier 1 only: no Radix, no animation libs.

Signed-off-by: Haoqing Wang <haoqing@users.noreply.github.com>
…ates

Reshape the renderer so the app feels like a real product even before any
AI call succeeds. All Tier 1, no new prod deps.

Added:
- TopBar with breadcrumb + 3 icon-buttons (palette / theme / settings),
  using the macOS hiddenInset drag region.
- Settings overlay with 4 tabs: Models (stub), Appearance (theme picker),
  Storage (config file path), Advanced (placeholder).
- CommandPalette overlay (Cmd+K) with 4 actions: New Design, Toggle
  Theme, Open Settings, Export (stub).
- ThemeToggle: persists to localStorage; index.html bootstraps the
  `.dark` class inline before React mounts to avoid FOUC.
- ToastViewport (Zustand-backed, auto-dismiss 4s, stack bottom-right)
  surfacing generation success and errors.
- PreviewPane with three explicit states: EmptyState (chips populate
  the prompt input), LoadingState (CSS shimmer), ErrorState (Retry +
  Copy Error card).
- useKeyboard hook: central keymap registry on plain addEventListener.
  Cmd+Enter sends, Cmd+, opens Settings, Cmd+K opens palette, Esc
  closes overlays.
- Sidebar extracted from App.tsx; App.tsx is now a slim composition.

Store gains: theme, settingsOpen, commandPaletteOpen, toasts, lastError,
plus retryLastPrompt + clearError.

No silent fallbacks: every error path pushes a toast and surfaces in
ErrorState. All UI uses var(--color-*) tokens; no hex literals; no new
hardcoded px sizes added.

Signed-off-by: Haoqing Wang <haoqing@users.noreply.github.com>
@hqhq1025
Copy link
Copy Markdown
Collaborator Author

Superseded by v2 (clean cherry-pick on top of latest main). See 3-v2 PR.

@hqhq1025 hqhq1025 closed this Apr 18, 2026
@hqhq1025 hqhq1025 deleted the wt/preview-ux branch April 18, 2026 07:48
hqhq1025 added a commit that referenced this pull request Apr 22, 2026
…opencode banner)

Three round-4 items closed at once — they all touch the import UX but
are small, so one commit keeps the diff readable:

1. (#3) parseDotEnv malformed-line warnings. The old parser silently
   dropped `GEMINI_API_KEY value` (space instead of `=`) with zero
   signal. Split into parseDotEnvLines (returns {vars, skipped}) +
   parseDotEnv (thin wrapper preserving the old signature). In
   readGeminiCliConfig, scan each file's skipped lines for anything
   that LOOKS like a GEMINI_API_KEY declaration but is missing `=`
   and surface a targeted warning — works even when the key
   eventually resolves from shell env, so the user knows their
   .env line is broken.

2. (#4) detectChatgptSubscription test coverage. Export the function
   and accept an optional `authPath` test-seam param. Four tests
   cover: chatgpt auth_mode → true, other auth_mode → false, ENOENT
   → false (silent), malformed JSON → false (loud, goes through the
   new logger call from the prior commit).

3. (#5) opencode banner shows provider names, not just a count.
   Before: "OpenCode config detected — import 4 providers?" left the
   user guessing WHICH four. Now: "OpenCode detected — import 4
   providers (OpenCode · Anthropic, OpenCode · OpenAI, OpenCode ·
   Google +1 more)?". Providers ride along in the banner state as
   `providerLabels: string[]`.

No functional regression; 779 → 787 desktop tests (+8).

Signed-off-by: hqhq1025 <1506751656@qq.com>
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