Skip to content

fix(ui): align composer model and voice controls - #1740

Merged
Astro-Han merged 3 commits into
apache:mainfrom
sunheyi6:codex/fix-composer-model-voice-controls
Aug 3, 2026
Merged

fix(ui): align composer model and voice controls#1740
Astro-Han merged 3 commits into
apache:mainfrom
sunheyi6:codex/fix-composer-model-voice-controls

Conversation

@sunheyi6

@sunheyi6 sunheyi6 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Rebind the composer model and thinking-level selectors to Maka palette tokens, including their popovers.
  • Present both selectors as flat, borderless toolbar controls while retaining a themed keyboard-focus state.
  • Hide voice capture and realtime voice buttons until the corresponding connection and model are configured.
  • Refresh the shell settings mirrors when Settings closes so voice control visibility updates without restarting.
  • Add focused coverage for unconfigured, independently configured, and whitespace-only voice routes.

Why

The Astryx selector subtree inherited neutral theme colors from its closer Theme wrapper, so the model controls stayed white/gray after a Maka palette change. Voice callbacks were also always passed to the composer, which made the buttons render before a usable voice route existed.

User impact

Composer model controls now match the selected theme and no longer look like nested form fields. Voice controls appear only when their related Settings configuration is complete.

Validation

  • npm --workspace @maka/desktop run typecheck
  • npm --workspace @maka/desktop run build:main
  • node --test apps/desktop/dist/main/__tests__/voice-composer-availability.test.js
  • npm --workspace @maka/desktop run build:renderer
  • git diff --check

@sunheyi6
sunheyi6 marked this pull request as ready for review August 1, 2026 03:15
…oser voice-route gating + model-switcher chrome

Resolve conflicts in app-shell.tsx and model-switcher.css between
main (Astryx ChatSurfaceLayout / quiet composer chrome apache#1835) and
the PR (voice availability gating apache#1740):

- Keep main ChatSurfaceLayout structure; apply PR gating
  (voiceCaptureConfigured / realtimeVoiceConfigured) to composer
  voice callbacks; add realtimeVoiceState + onToggleRealtimeVoice.
- closeSettings now calls refreshShellSettings(), which hydrates
  permission mode and both voice routes from useShellAppearance.
- Drop main composerVoiceCaptureReady local mechanism, superseded
  by merged refreshShellSettings hydration (mount + external change
  + settings close).
- Keep main apache#1835 astryx-selector flat-toolbar chrome; retain PR
  palette-token rebinding in .maka-model-selection-controls.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2. The realtime half is dead plumbing. realtimeVoiceConfigured has no reader; voiceComposerAvailability().realtime and the realtimeVoiceState prop wired in app-shell feed Composer props that are marked @deprecated and never rendered. The capture half is a real simplification: the separate effect collapses into refreshShellSettings. Keep that, drop the realtime state, or actually render the control.

P3. The useShellAppearance docstring still says closeSettings re-reads only the default permission mode; it now calls refreshShellSettings().

The realtime half of the composer voice gating fed deprecated, never-rendered
Composer props; only the capture route gates real UI. Remove the realtime
state and narrow voiceComposerAvailability to the recognition route. Also
refresh the useShellAppearance docstring to match refreshShellSettings().

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: MERGE-READY ✅ (2 independent reviewer passes)

DeepSeek review of the full diff plus the incremental commit (a38c1af0, drop dead realtime voice-route state) on top of the previously approved head:

  • Incremental commit is clean: realtimeVoiceConfigured state, voiceComposerAvailability().realtime field, and app-shell wiring removed completely (zero grep hits); the capture gating path is untouched and behavior-preserving.
  • Gating equivalence verified: the three refresh triggers (mount / external change / settings close) fully cover the old effect's triggers with one fewer duplicate subscription; trim-based checks are verbatim-equivalent to the old contract.
  • CSS token binding verified: all 11 Astryx target tokens and 7 Maka source tokens exist; Popover has no createPortal, so token cascade reaches the popover; oklch(from …) is supported by Electron 43.
  • No merge conflicts with current main (merge-tree clean); tests pass; CI green (changes/typecheck/test/e2e).

Non-blocking P3 (optional, do not gate):

  1. Two dead prop wirings remain (realtimeVoiceState/onToggleRealtimeVoice at app-shell.tsx:2228/2236, never read by Composer) — the realtime cleanup should ideally include these two lines; safe to remove in a follow-up.
  2. voiceComposerAvailability returns a single-field { capture } object — could be a plain boolean; cosmetic.
  3. On settings-refresh failure, a stale-true mic visibility can persist (pre-existing trade-off of the shared refresh path, not introduced here).

None block merging.

@Astro-Han
Astro-Han merged commit df5abd4 into apache:main Aug 3, 2026
5 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