1. Menu now brighter (0xFF3A3A4A) for better contrast
2. Orb on main page always visible (static when off, pulsing when on)
3. Implemented camera capture (saves to MediaStore, loads as attachment)
4. Implemented file picker (any file type)
5. Attachment type auto-detected (image vs file) based on MIME
- Top row of attachment buttons: Camera | Photos | Files
- Dark menu background (0xFF1E1E2E) for contrast
- Styled menu items with icons and trailing values
- Session and Thinking level show current value on right
- Dividers between sections
- TODO: Implement camera capture and file picker
Redesigned ChatComposer with Telegram/ChatGPT-style layout:
- Hamburger menu on left (session, thinking level, attach, refresh)
- Rounded text input field in center
- Right button transforms:
- Empty: Mini orb (PTT) with mic icon
- Has text: Send button (arrow up)
- Running: Stop button
- Haptic feedback on orb tap
- Compact connection status pill below
- Talk overlay shows centered when voice active
- Reduced orb size from 360dp to 200dp
- Moved orb to bottom of screen
- Chat messages display above the orb (max 400dp height)
- Cleaner assistant UI with chat and PTT in one view
- Orb is now always visible (not just when talk mode is on)
- Tap to toggle talk mode on/off
- When inactive: static, dimmed, shows 'Tap to talk'
- When active: pulsing animation with status text
- Haptic feedback on tap
OPPO's PhoneWindowManager sets IsQuickLaunchSupport=false for apps with
VoiceInteractionService, blocking long-press power button from triggering
the assistant. Disabling the service makes OPPO fall back to the standard
ACTION_ASSIST intent path (same as App Manager).
- Disabled ClawdbotVoiceInteractionService and SessionService
- MainActivity now handles ASSIST intents directly
- Tested working on OnePlus 13 (ColorOS)
When the user sends a message while reading older messages, scroll to
bottom so they can see their sent message and the response.
Fixes#2470
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixed issue where trigger words would disappear when typing or when adding new trigger words. The problem was that `swabbleTriggerWords` changes were triggering `VoiceWakeRuntime.refresh()` which sanitized the array by removing empty strings in real-time.
Solution: Introduced local `@State` buffer `triggerEntries` with stable UUID identifiers for each trigger word entry. User edits now only affect the local state buffer and are synced back to `AppState` on explicit actions (submit, remove, disappear). This prevents premature sanitization during editing.
The local state is loaded on view appear and when the view becomes active, ensuring it stays in sync with `AppState`.