Skip to content

Comments

Consolidate audio recording components into the new message composer structure#6150

Merged
andremion merged 12 commits intov7from
redesign/AND-1039-consolidate-audio-recording-components-into-the-new-message-composer-structure
Feb 13, 2026
Merged

Consolidate audio recording components into the new message composer structure#6150
andremion merged 12 commits intov7from
redesign/AND-1039-consolidate-audio-recording-components-into-the-new-message-composer-structure

Conversation

@andremion
Copy link
Contributor

@andremion andremion commented Feb 12, 2026

Goal

Prepare the Compose audio recording components for the upcoming design update by consolidating them into a self-contained structure aligned with the new message composer.

Implementation

  • Unified all recording UI into a single internal AudioRecordingButton that manages the full recording lifecycle, removing the audioRecordingContent slot from MessageComposer and MessageComposerAudioRecordingContent from ChatComponentFactory
  • Split the monolithic DefaultMessageComposerRecordingContent into focused files: AudioRecordingButton, AudioRecordingContent, AudioRecordingGesture, and AudioRecordingPermission
  • Inlined MessageInput directly into DefaultMessageComposerContent
  • Extracted SnackbarPopup as a reusable component
  • Replaced hardcoded gesture thresholds with platform viewConfiguration values
  • Added haptic feedback and spring animation to the recording interaction

🎨 UI Changes

No visual changes intended — this is a structural refactor of the existing recording UI.

Testing

  • Long-press to record, drag up to lock, slide left to cancel

Summary by CodeRabbit

Release Notes

  • Improvements
    • Redesigned audio recording UI with enhanced gesture controls and streamlined permission handling.
    • Updated guidance text for recording clarity ("Hold to record. Release to send").
    • Added new theme color property for improved visual consistency.
    • Optimized notification display with improved snackbar implementation.

@andremion andremion added the pr:breaking-change Breaking change label Feb 12, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 12, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled.

🎉 Great job! This PR is ready for review.

@andremion andremion marked this pull request as ready for review February 12, 2026 15:35
@andremion andremion requested a review from a team as a code owner February 12, 2026 15:35
@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Walkthrough

This PR redesigns the audio recording UI in the message composer by introducing new comprehensive recording components (AudioRecordingButton, AudioRecordingContent, AudioRecordingGesture, AudioRecordingPermission) while removing the previous recording UI implementation. The MessageComposer public API is restructured—removing the audioRecordingContent parameter and altering function signatures—alongside internal reorganization of compose singletons and a new SnackbarPopup wrapper.

Changes

Cohort / File(s) Summary
Audio Recording Redesign
src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingButton.kt, AudioRecordingContent.kt, AudioRecordingGesture.kt, AudioRecordingPermission.kt
New comprehensive audio recording UI components with state-driven rendering (Idle, Hold, Locked, Overview), gesture handling with drag-to-cancel, permission management via Accompanist, haptic feedback, and floating UI elements for lock icons and mic button.
MessageComposer Refactoring
src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt, api/stream-chat-android-compose.api
Removed audioRecordingContent parameter from public MessageComposer overloads; replaced internal SnackbarPopup usage with new SnackbarPopup composable; reorganized internal compose singletons (ComposableSingletons$DefaultMessageComposerRecordingContentKt renamed to ComposableSingletons$AudioRecordingButtonKt, added ComposableSingletons$SnackbarPopupKt).
Removed Old Recording Components
src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/DefaultMessageComposerRecordingContent.kt, MessageComposerDefaults.kt
Deleted entire DefaultMessageComposerRecordingContent.kt file (865 lines) containing old audio recording UI; removed internal DefaultMessageComposerInput composable with its parameter list and conditional rendering logic.
UI/Layout Updates
src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt, suggestions/SuggestionList.kt
Made centerContent in MessageInput conditional based on recording state (replaced with Spacer during active recording); changed SuggestionList PopupPositionProvider from instance creation to reference.
Theme and Factory Updates
src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt, StreamColors.kt, util/SnackbarPopup.kt
Updated ChatComponentFactory to use new AudioRecordingButton instead of old recording components; added backgroundCoreInverse and backgroundCoreSurfaceSubtle color properties to StreamColors; introduced new SnackbarPopup composable wrapping SnackbarHost in a Popup.
Test and Resource Updates
src/test/kotlin/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingButtonTest.kt, src/androidTestE2eDebug/kotlin/io/getstream/chat/android/compose/pages/MessageListPage.kt, res/values/strings.xml, stream-chat-android-ui-components/src/main/res/values/strings.xml
Renamed test class and methods from DefaultMessageComposerRecordingContent to AudioRecordingButton; updated UI element selector for audio recording button resource ID; updated hold-to-record instruction text from "Hold to start, release to send." to "Hold to record. Release to send".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested labels

pr:improvement

Suggested reviewers

  • gpunto
  • VelikovPetar

Poem

🎙️ A hop and a pop, the recorder takes flight,
Hold-to-record flows, permission's done right,
Snackbar popups whisper "let's start the tale,"
Colors inverse and gestures prevail,
Fresh audio blooms where old code did pale. 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the primary change: consolidating audio recording components into a unified structure within the new message composer, matching the main refactoring objective.
Description check ✅ Passed Description is well-structured with Goal, Implementation, and Testing sections. However, UI Changes section lacks required before/after screenshots and videos per template, and Contributor/Reviewer checklists are incomplete.
Linked Issues check ✅ Passed The PR successfully implements the coding requirements from AND-1039 by consolidating audio recording components into a self-contained AudioRecordingButton structure aligned with the new message composer design.
Out of Scope Changes check ✅ Passed All changes are scoped to audio recording component consolidation and message composer structure alignment. Updates to color properties (backgroundCoreInverse, backgroundCoreSurfaceSubtle) in StreamColors align with the new design system from AND-1039.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch redesign/AND-1039-consolidate-audio-recording-components-into-the-new-message-composer-structure

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingButton.kt`:
- Around line 590-593: The `@Suppress`("MagicNumber") above PreviewWaveformData
needs a short justification comment to make the suppression intentional: update
the declaration for PreviewWaveformData to include an inline comment or KDoc
that explains these numeric literals are static preview waveform sample values
(used only in previews, not production logic) and why the MagicNumber rule is
acceptable here, or replace the suppression with an `@OptIn` usage if applicable;
reference the symbol PreviewWaveformData and keep the suppression only after
adding that rationale.
- Around line 595-682: Replace the Compose `@Preview` annotations on the preview
functions (AudioRecordingButtonIdlePreview, AudioRecordingButtonHoldPreview,
AudioRecordingButtonLockedPreview, AudioRecordingButtonOverviewPreview) to use
the project's StreamPreview helper annotation (e.g., `@StreamPreview`) while
preserving any existing size overrides like showBackground and heightDp; ensure
any helper import is added and keep the preview bodies unchanged so the previews
still render the same content (retain ChatPreviewTheme wrappers and size
modifiers).

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingPermission.kt`:
- Around line 143-186: AudioRecordingPermissionRationale currently relies on
TimedPopup's 1000ms default which is too short for reading the rationale and
tapping "Settings"; update the TimedPopup invocation inside
AudioRecordingPermissionRationale to use a longer dismissTimeoutMs (e.g.,
3000–4000) or remove the auto-dismiss behavior and make it
dismiss-only-on-action by passing an explicit dismissTimeoutMs value or
switching to a non-timed popup API; edit the TimedPopup call in
AudioRecordingPermissionRationale to include dismissTimeoutMs = 3000 (or
implement no timeout) so the rationale/card and Settings button remain visible
long enough for users to read and interact.
🧹 Nitpick comments (4)
stream-chat-android-compose/api/stream-chat-android-compose.api (1)

2575-2576: Document the new state-based MessageComposer overload as the preferred pattern.

Both MessageComposer overloads (ViewModel-based and state-based) coexist in the public API, so this is an additive change rather than a breaking one. However, if the new MessageComposerState-based variant is intended as the recommended pattern going forward, consider adding a migration note to release documentation to guide developers toward it. The state-based approach appears designed for more flexibility, so clarity on when to use each would be valuable for API consumers.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingContent.kt (1)

205-221: Modifier.size(micStyle.size) on the Icon is redundant given the parent Box constraints.

The parent Box is sized to micStyle.size with inner padding, so the Icon's available space is already smaller than micStyle.size. The explicit size modifier on the Icon won't achieve the declared size. Consider using Modifier.fillMaxSize() on the Icon instead, or removing the padding from the Box and sizing the Icon directly.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingPermission.kt (1)

96-101: Consider making AudioRecordingPermission a data class or adding equals/hashCode.

Since instances are created inside remember(state) and used for recomposition comparisons, the current class identity-based equality means any recomposition that recreates state will allocate a new wrapper. In practice this is likely fine since remember(state) already handles the caching, but making it a data class (or at least documenting the intent) would make the stability contract clearer for future maintainers.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/internal/AudioRecordingButton.kt (1)

336-339: Avoid keeping a Popup mounted when no hint is shown.

Guarding this keeps popups lightweight when the snackbar is idle.

♻️ Suggested guard
-    SnackbarPopup(
-        hostState = hint.snackbarHostState,
-        snackbar = { AudioRecordingSnackbar(it) },
-    )
+    if (hint.snackbarHostState.currentSnackbarData != null) {
+        SnackbarPopup(
+            hostState = hint.snackbarHostState,
+            snackbar = { AudioRecordingSnackbar(it) },
+        )
+    }

@github-actions
Copy link
Contributor

github-actions bot commented Feb 12, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.66 MB 0.41 MB 🟡
stream-chat-android-ui-components 10.60 MB 10.82 MB 0.22 MB 🟢
stream-chat-android-compose 12.81 MB 11.87 MB -0.95 MB 🚀

Copy link
Contributor

@gpunto gpunto left a comment

Choose a reason for hiding this comment

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

Looks good, I left mostly nitpicks

@andremion andremion force-pushed the redesign/AND-1039-consolidate-audio-recording-components-into-the-new-message-composer-structure branch from d07fb44 to 124df19 Compare February 13, 2026 09:38
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
66.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@andremion andremion enabled auto-merge (squash) February 13, 2026 12:12
@andremion andremion disabled auto-merge February 13, 2026 12:12
@andremion andremion merged commit 3c6cf93 into v7 Feb 13, 2026
17 of 20 checks passed
@andremion andremion deleted the redesign/AND-1039-consolidate-audio-recording-components-into-the-new-message-composer-structure branch February 13, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:breaking-change Breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants