Conversation
Lower the ExoPlayer controller auto-hide timeout to 2s in the chat media viewer, and fix a feedback loop where hiding/showing the system bars re-triggered the controller to reappear mid fade-out, flickering forever: WindowInsets.systemBars animates across many frames while the bars hide/show, and reapplying the controller's child-view margins on every one of those frames fought the controller's own hide animation. Switch to WindowInsets.systemBarsIgnoringVisibility, which stays constant regardless of our own show/hide calls, in both the chat media viewer and the full-screen file viewer. Also drop the now-dead video branch in FullScreenMediaActivity/ FileViewerUtils: video attachments are routed to the media viewer before mimetype dispatch ever reaches it, so FullScreenMediaActivity only ever serves audio now. Removes the AUDIO_ONLY intent extra and isAudioOnly plumbing accordingly. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…tivity Extend the voice-message playback infrastructure to also handle generic (non-voice) audio file attachments, so they play inline in the chat bubble like voice messages do, instead of opening a separate full-screen activity. The new bubble is deliberately distinct from a voice message: a plain Material3 slider instead of a waveform, a generic file icon, the real filename shown, and no playback-speed control - both because a long audio file (podcast, song) is expensive to waveform-decode client-side the way short voice recordings are, and because the difference itself makes it visually obvious this is a file, not a voice note. - ChatMessageUi: new MessageTypeContent.AudioFile case, dispatched for audio-mimetype attachments; reuses ChatMessage's existing voice playback-state fields rather than adding a parallel set, since actual playback already goes through the same MediaController/ VoiceMessageMediaService session for both message types. - ChatViewModel.syncVoiceMessageUiState: now updates AudioFile content too, not just Voice - without this, audio-file playback would run but the UI would never reflect it. - ChatActivity: gate waveform decoding to real voice messages only, and show the filename (not "Voice Message") in the system media notification for audio files. - FileViewerUtils: removed openAudioView() and its dispatch branch - audio files never call onFileClick/openFile anymore, same as voice messages never did. - Shared Items gallery (Audio/Voice/Recording tabs): tapping a row now jumps to and highlights the message in chat, reusing the same navigate-to-message intent pattern already used by search results, instead of opening a player from the gallery. - Removed FullScreenMediaActivity/FullScreenMediaScreen entirely (its manifest entry, both FullScreenMediaTheme style variants, and the AUDIO_ONLY intent extra it existed for) now that nothing routes audio playback through it. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
The plain Material3 Slider used its default colors (primary/ surfaceVariant), which read as nearly invisible against the message bubble background. Give it explicit colors instead: primary for the thumb/played portion (the app's normal accent, recognizable without being the punchier inversePrimary voice messages' waveform uses), and a 40%-alpha onPrimaryContainer for the unplayed rail, visible without looking as bold as full-strength text-contrast color. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Two related bugs in onVoiceClick's prepare-and-play flow, both only reachable now that generic audio files (not just voice messages) go through it: - isDownloadingVoiceMessage was only ever reset back to false inside setUpWaveform, once waveform decoding finished. Audio files skip waveform decoding entirely, so once downloadFileToCache set it true, nothing ever cleared it - the spinner stayed up forever and the play/pause button became permanently unreachable. Extracted the shared "start playback" step into finishPreparing(), which now resets the flag directly for non-voice messages instead of relying on setUpWaveform to do it. - The MediaController's currentMediaItem can outlive the local cache file it points to - e.g. clearing the app's cache only deletes files on disk, not the (service-hosted, long-lived) MediaController's in-memory state. Re-preparation was skipped whenever a message's mediaId already matched the controller's loaded item, regardless of whether the file was actually still there, falling through to a bare controller.play() on a stale reference that could never succeed (ExoPlayer FileNotFoundException) and leaving pause/resume unreachable. Now also re-prepares (and so re-downloads) whenever the file is missing, even if the mediaId already matches. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
The filename was single-line with no overflow handling and no width constraint of its own, so a long name could run past the message bubble's edge instead of wrapping or truncating. Allow it to wrap onto a second line first, only ellipsizing if it's still too long, and constrain it to the row's remaining width (after the icon) so it wraps within the bubble instead of overflowing past it. Assisted-by: Claude Code:claude-sonnet-5 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
mahibi
marked this pull request as ready for review
September 18, 2026 12:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Generic audio attachments now play inline in the chat bubble, the same
way voice messages already do, instead of opening a separate full-screen
activity:
- New
MessageTypeContent.AudioFile+AudioFileMessagecomposable,visually distinct from a voice message (plain progress slider instead
of a waveform, generic file icon, filename shown, no speed control -
partly because decoding a waveform for a long audio file client-side
is expensive, unlike short voice recordings).
- Reuses the existing voice-message
MediaController/VoiceMessageMediaServiceplayback session, so only one thing playsat a time regardless of type, and background/lock-screen controls
work identically for both.
-
FullScreenMediaActivityand its Compose screen are removed entirely,along with their manifest entry and both
FullScreenMediaThemestylevariants - nothing routes audio playback through them anymore.
- Shared Items gallery (Audio/Voice/Recording tabs): tapping a row now
jumps to and highlights the message in chat instead of opening a
player, reusing the app's existing jump-to-message navigation.
- Follow-up fixes found during testing: a stuck loading spinner once
waveform decoding was skipped for audio files, a
MediaControllerthat could hold a stale reference to a file deleted by clearing the
app's cache (skipping re-download indefinitely), seek-bar contrast
against the message bubble, and long filenames wrapping instead of
overflowing the bubble.
Video controls auto-hide delay + system bar flicker fix (in-chat media
viewer and the standalone full-screen file viewer): lowers the ExoPlayer
controller auto-hide timeout to 2s, and fixes a feedback loop where
hiding/showing the system bars re-triggered the controller to reappear
mid fade-out, causing it to flicker indefinitely.
🖼️ Screenshots
🏁 Checklist
/backport to stable-xx.x🤖 AI (if applicable)