Backend now guarantees msg_type is always populated. Changed all server
message handlers (stream_chunk, stream_end, thinking, tool_progress, error,
voice_transcript, review) to use wsMsg.msgType with safe fallback defaults
instead of hardcoded values.
Also added missing ProGuard keep rules for UI screens/components/overlay to
prevent R8 from stripping composables called via navigation lambdas.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Navigation compose lambdas in NavGraph may not be traced by R8's call
graph, causing screen composables to be stripped in release builds.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Hidden tabs with graphicsLayer{alpha=0f} still intercepted touch events.
Replaced with offset(x=2000.dp) + parent clipToBounds() so hidden composables
are off-screen and cannot capture touches meant for the visible tab.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ChatScreen: restructure to Box overlay layout so only input area
rises with IME, messages stay fixed. Add opaque background to input
area. Use reverseLayout with newest-first animation order.
- OverlayContent: remove all manual IME detection — system forces
adjust=pan on VoiceInteractionSession windows, so manual padding
caused double offset. Let system handle IME naturally.
- ChatRepositoryImpl: add messageRemovals flow to clean up wrapping
stream_end/response when review/multi_message items arrive later.
Track lastResponseId in both stream_end and response handlers.
- ChatViewModel/OverlayViewModel: fix dedup to check by message ID
only. Sort descending (newest first). Observe messageRemovals.
- NavGraph: keep all tabs composed with graphicsLayer alpha toggle —
prevents ChatScreen destruction and re-render on tab switch.
- CyreneVoiceInteractionSession: defer configureWindow via post()
to override system softInputMode flags.
- AndroidManifest: set windowSoftInputMode=adjustNothing on main
activity.
- Add WebSocketKeepAliveService for background connection persistence.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
R8 was stripping Android components (services, application),
Room entities, Koin modules, and ViewModels — causing crash
when VoiceInteractionService was invoked via power button.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix: dark mode white backgrounds via transparent windowBackground, decorView color, and explicit Surface backgrounds on IoT/Profile/MainScreen
- Fix: dark mode text colors in ProfileScreen (nickname, account info, assistant status)
- Feat: long-press chat bubble to copy message text via DropdownMenu
- Feat: notification deduplication — track notified message IDs, clear on foreground
- Feat: cancel all notifications when app enters foreground
- Feat: biometric/device-credential verification before clearing local messages
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add auto_screen_context preference (boolean, default false) to DataStore
- Add Switch toggle in Settings > Voice section to control automatic screen
content reading when assistant is invoked via power button
- CyreneVoiceInteractionSession onShow now checks the preference before
calling AccessibilityService to read and send screen content
- Fix status bar white in dark mode: MainActivity now observes theme mode
preference (light/dark/auto) and passes resolved boolean to CyreneTheme
- CyreneTheme sets statusBarColor, navigationBarColor, and
isAppearanceLightStatusBars/isAppearanceLightNavigationBars explicitly
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Restore FLAG_TRANSLUCENT_STATUS and FLAG_TRANSLUCENT_NAVIGATION on
VoiceInteractionSession window to let content extend behind system bars
- Move window configuration from onCreateContentView to onShow (window
is guaranteed available at this point)
- Replace statusBarsPadding/navigationBarsPadding with manual status bar
height calculation — Compose WindowInsets may not receive proper values
in VoiceInteractionSession overlay windows
- Keep SOFT_INPUT_ADJUST_NOTHING + imePadding on InputArea for correct
IME behavior (full-screen IME pushes input, floating IME does not)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Reconnection: unlimited retries with capped backoff, forceReconnect on foreground
and manual refresh when offline
- Overlay: fix status bar coverage, remove scrim, fix IME layout (messages fixed
at top, only full-screen IME pushes input), handle process-kill by eager
ViewModel resolution with try-catch
- Profile: cache-first rendering, cloud refresh on each visit, silent fallback
to cache on failure
- Messages: fix message swallowing by tracking DB observer job and using atomic
StateFlow.update(), add dedicated isAssistantStreaming state for reliable
typing indicator
- History: history_response handler now emits to live message stream, HTTP
fallback waits for WS connection before requesting history
- Foreground: always request history on foreground to catch cross-device messages
- Log viewer: enhanced with All tab, auto-scroll, new categories (HTTP, voice, general),
added log points for app lifecycle and overlay events
- Settings: added About page with project link (https://git.yeij.top/AskaEth/Cyrene-For-Android)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>