--- phase: 37-web-chat-voice-ui plan: 03 subsystem: ui tags: [react, voice, audio, shadcn, lucide-react, localStorage, tailwind] # Dependency graph requires: - phase: 36-voice-pipeline-foundation provides: POST /api/synthesize and POST /api/transcribe endpoints; voiceMode persisted via nexus-settings - phase: 37-01 provides: COOP/COEP headers for SharedArrayBuffer; VAD ONNX assets provides: - ChatVoicePlayer: inline audio player with play/pause, auto-play, blob URL cleanup - ChatVoiceBadge: Voice badge + SPOKEN/DETAILED parsing + collapsible full markdown - VoiceModeToggle: three-pill Text/Voice In/Full Voice toggle with nexus-settings persistence - useVoiceMode: hook for reading/writing voiceMode via PATCH /api/nexus/settings affects: [37-04, ChatMessage integration, ChatInput integration] # Tech tracking tech-stack: added: [] patterns: - Blob URL lifecycle: createObjectURL on fetch response, revokeObjectURL in onEnded and cleanup - SPOKEN/DETAILED regex parsing for dual-format voice responses - Three-pill toggle pattern with active/inactive Tailwind classes + role="group" + aria-label key-files: created: - ui/src/components/ChatVoicePlayer.tsx - ui/src/components/ChatVoiceBadge.tsx - ui/src/components/VoiceModeToggle.tsx - ui/src/hooks/useVoiceMode.ts modified: [] key-decisions: - "useVoiceMode hook created in plan 37-03 (not 37-02) to unblock VoiceModeToggle — parallel execution" - "ChatVoicePlayer fetches audio on text change, not on play — pre-loads audio for smoother UX" - "Auto-play preference stored in localStorage (nexus:voice:autoplay), not nexus-settings — avoids server round-trip for fast UX" patterns-established: - "Pattern 1: blob URL cleanup — always revokeObjectURL in both onEnded and effect cleanup to prevent memory leaks" - "Pattern 2: voice badge renders differently per messageType — voice_input shows badge+text only; voice_full adds player+collapsible" requirements-completed: [WCHAT-04, WCHAT-05, WCHAT-06] # Metrics duration: 2min completed: 2026-04-04 --- # Phase 37 Plan 03: Voice Output Components Summary **Inline audio player (ChatVoicePlayer), voice badge with collapsible markdown (ChatVoiceBadge), and three-pill mode toggle (VoiceModeToggle) — complete output-side voice UI** ## Performance - **Duration:** 2 min - **Started:** 2026-04-04T02:35:25Z - **Completed:** 2026-04-04T02:37:21Z - **Tasks:** 2 - **Files modified:** 4 ## Accomplishments - ChatVoicePlayer: POST /api/synthesize → blob URL → native `