Skip to content

Conversation

@gpunto
Copy link
Contributor

@gpunto gpunto commented Jan 15, 2026

🎯 Goal

AND-997: Update reply design

Update design of quoted message, which is the same component in both the composer and messages.

🛠 Implementation details

  • Removed QuotedMessageStyle as we agreed not to have intermediate styles
  • Introduced a QuotedMessageBodyBuilder to encapsulate the logic to calculate what we should show (text, icon, preview)
  • Removed QuotedMessageTextFormatter in favor of the builder
  • Removed QuotedAttachmentFactory as it doesn't fit the use case anymore
  • Removed "product" attachment type, as that doesn't exist in the backend
  • Note: I didn't update the attachment filetype icons, I'll do that in a follow up as it seems it might entail more than just replacing icons

🎨 UI Changes

Figma spec

Before After
Screenshot_20260115_113421 Screenshot_20260115_103350

🧪 Testing

You can test this in the sample app by just replying to messages and verifying that we render what's expected.

☑️Contributor Checklist

General

  • I have signed the Stream CLA (required)
  • Assigned a person / code owner group (required)
  • Thread with the PR link started in a respective Slack channel (#android-chat-core or #android-chat-ui) (required)
  • PR is linked to the GitHub issue it resolves

Code & documentation

  • Changelog is updated with client-facing changes
  • New code is covered by unit tests
  • Comparison screenshots added for visual changes
  • Affected documentation updated (KDocs, docusaurus, tutorial)

☑️Reviewer Checklist

  • UI Components sample runs & works
  • Compose sample runs & works
  • UI Changes correct (before & after images)
  • Bugs validated (bugfixes)
  • New feature tested and works
  • Release notes and docs clearly describe changes
  • All code we touched has new or updated KDocs
  • Check the SDK Size Comparison table in the CI logs

🎉 GIF

Please provide a suitable gif that describes your work on this pull request

Summary by CodeRabbit

  • New Features

    • Add a cancel action in the message composer to dismiss active message actions.
  • Updates

    • Redesigned quoted message UI with unified layout, richer previews (thumbnails, play indicator) and improved media labels.
    • Composer now exposes edit action only (reply path removed).
    • Removed product attachment type support; product attachments may no longer open.
    • Simplified location labels (removed emoji).

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 15, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.25 MB 0.00 MB 🟢
stream-chat-android-offline 5.48 MB 5.48 MB 0.00 MB 🟢
stream-chat-android-ui-components 10.62 MB 10.61 MB -0.01 MB 🚀
stream-chat-android-compose 12.84 MB 11.67 MB -1.17 MB 🚀

@gpunto gpunto force-pushed the redesign/reply branch 2 times, most recently from e316231 to 08e62ef Compare January 15, 2026 12:02
@gpunto
Copy link
Contributor Author

gpunto commented Jan 15, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

Walkthrough

Removes multiple quoted-message composables and formatting APIs, introduces an internal QuotedMessageBodyBuilder, threads an onCancelAction through composer/input components, updates theme/color APIs (removing quoted-message styles), removes PRODUCT attachment type, adds drawable assets and string changes, and adds tests for the new body builder.

Changes

Cohort / File(s) Summary
Quoted-message composables removed
stream-chat-android-compose/src/main/java/.../QuotedMessageAttachmentContent.kt, .../QuotedMessageContent.kt, .../QuotedMessageText.kt, .../attachments/content/*QuotedContent.kt, .../attachments/factory/QuotedAttachmentFactory.kt
Deleted multiple public composables and an attachment factory related to quoted-message attachment and text rendering.
Quoted-message refactor & builder
stream-chat-android-compose/src/main/java/.../QuotedMessage.kt, .../QuotedMessageBodyBuilder.kt
Replaces slot-based QuotedMessage with an internal Row-based implementation and adds internal QuotedMessageBodyBuilder + rememberBodyBuilder to compute quoted-body content.
Composer / Input cancel flow
.../MessageInput.kt, .../MessageComposer.kt, .../ChatComponentFactory.kt, stream-chat-android-compose-sample/.../MessagesActivity.kt, docs snippets
Adds onCancelAction parameter propagated from ChatComponentFactory → MessageComposer → MessageInput; sample/docs wired to call composerViewModel.dismissMessageActions(). Also extracts ComposerTrailingIcon in sample.
Theme & style API changes
.../ChatTheme.kt, .../MessageTheme.kt, .../StreamColors.kt, stream-chat-android-compose.api
Removes quoted-message theme properties and formatter from ChatTheme/MessageTheme; updates StreamColors with new semantic color props and removes deprecated quoted color props; large public API surface/signature updates documented in .api file.
Quoted-message formatting removed
.../QuotedMessageTextFormatter.kt, .../QuotedMessageStyle.kt
Deletes QuotedMessageTextFormatter interface, Default/Composite formatter logic and QuotedMessageStyle data class and helpers.
Tests added/removed
src/test/.../QuotedMessageBodyBuilderTest.kt, removed DefaultQuotedMessageTextFormatterTest.kt, trimmed quoted-attachment tests
Adds extensive unit tests for QuotedMessageBodyBuilder; removes tests tied to the deleted formatter and some quoted-attachment tests.
Resources added/updated
stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_*.xml (camera, chart, file, link, map_pin, microphone, play_solid, video_outline), .../values/strings.xml
Adds eight vector drawable icons; updates and adds quoted-message string/plural resources and removes some old tag strings; ui-common strings: removed emoji prefixes from location labels.
Core model & routing
stream-chat-android-core/src/main/java/.../AttachmentType.kt, stream-chat-android-core/api/..., .../Mother.kt, .../AttachmentDestination.kt
Removes AttachmentType.PRODUCT constant, updates fixtures and removes explicit PRODUCT handling in attachment destination routing.
StreamAttachmentFactories
.../StreamAttachmentFactories.kt
Removes defaultQuotedFactories() and quoted attachment import; quoted factory no longer part of defaults.
Docs & samples
stream-chat-android-docs/..., stream-chat-android-ui-guides/...
Updates docs and samples to remove quoted-formatter usage and to wire the new onCancelAction in MessageInput examples.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as MessagesActivity (Compose)
    participant Composer as MessageComposer
    participant Input as MessageInput
    participant VM as ComposerViewModel / ListViewModel

    User->>UI: Tap cancel icon on quoted composer
    UI->>Composer: onCancelAction()
    Composer->>Input: forward onCancelAction
    Input->>VM: composerViewModel.dismissMessageActions()
    VM-->>UI: state updated (actions dismissed)
    UI-->>User: UI hides quoted composer / updates state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

compose, ui-components

Suggested reviewers

  • VelikovPetar
  • andremion

Poem

🐰 A tiny hop through changed UI,

Old quotes tucked out of view,
New builder hums beneath the hay,
Cancel hops the clutter away,
Fresh icons prance — let code rejoice!

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.21% 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 The title clearly and concisely describes the main change: updating the design of quoted messages, which is the primary focus of this PR.
Description check ✅ Passed The description follows the template structure with Goal, Implementation details, UI Changes (including before/after screenshots), and Testing sections completed. All critical information is present.
Linked Issues check ✅ Passed The PR implements the objectives of AND-997 by updating the quoted message design, removing deprecated styling components, introducing QuotedMessageBodyBuilder, and removing QuotedAttachmentFactory and PRODUCT type.
Out of Scope Changes check ✅ Passed All changes directly support the quoted message redesign objective. Removals of QuotedMessageStyle, QuotedMessageTextFormatter, and QuotedAttachmentFactory align with the stated implementation approach. Color and string resource updates support the new design.

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

✨ Finishing touches
  • 📝 Generate docstrings

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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
stream-chat-android-compose/api/stream-chat-android-compose.api (1)

3544-3578: MessageTheme / StreamColors data-class-style API churn (componentN, copy, constructor arity) will break destructuring and compiled consumers.
If these are intentionally part of the public API, try to minimize reorder/add churn (or discourage destructuring in docs). Where possible, prefer additive APIs (new named getters) over constructor/copy signature growth to keep ABI steadier.

Also applies to: 3625-3714

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt (1)

68-83: Missing KDoc for the new onCancelAction parameter.

The new onCancelAction parameter is undocumented in the KDoc comment block (lines 54-67). As per coding guidelines, public APIs should be documented with KDoc.

📝 Suggested KDoc addition

Add the following to the KDoc block:

  * `@param` onValueChange Handler when the value changes.
  * `@param` onAttachmentRemoved Handler when the user removes a selected attachment.
+ * `@param` onCancelAction Handler when the user cancels the current message action (e.g., reply or edit).
  * `@param` modifier Modifier for styling.
🤖 Fix all issues with AI agents
In `@stream-chat-android-compose/api/stream-chat-android-compose.api`:
- Around line 1851-1852: The public API for QuotedMessage exposes two Message
parameters in the generated signature which risks call-site confusion; update
the Kotlin declaration of QuotedMessage to use explicit, distinct parameter
names and a stable parameter order (e.g., quotedMessage vs
parentMessage/currentMessage) and ensure the function parameter list in the
source matches that order exactly, add KDoc to each parameter describing its
role, and consider providing a clear overload or named parameters usage example
in the source so call-sites and the generated signature are unambiguous.
- Around line 1683-1684: Add migration documentation and release notes stating
that the public Composable MessageInput now has a required onCancelAction
parameter (previously optional), describe that this is a breaking API change for
v7 releases, and provide a short migration example showing callers must pass an
onCancelAction lambda (or a default helper) when calling MessageInput; update
CHANGELOG / release notes to mention MessageInput and onCancelAction,
recommended migration code patterns, and that all internal callers were already
updated.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt`:
- Around line 149-172: The function MessageComposerQuotedMessage currently
ignores its modifier parameter; update the composable to apply the passed-in
modifier so callers can style it (e.g., use Box(modifier = modifier) or
Box(modifier = modifier.then(...)) ), ensuring the modifier is applied to the
root container (MessageComposerQuotedMessage's Box) and not dropped; keep
internal alignment/offset for ComposerCancelIcon unchanged and do not remove
QuotedMessage or ComposerCancelIcon.
- Around line 86-146: The quoted message body is being remembered only by
message and currentUser, so include the bodyBuilder (or its inputs) in the
remember keys to avoid stale UI: change the body remember call to include
bodyBuilder (e.g., remember(bodyBuilder, message, currentUser) {
bodyBuilder.build(message, currentUser) }) or include the relevant
theme-dependent inputs; also propagate the modifier parameter from
MessageComposerQuotedMessage into the QuotedMessage call so external
styling/test tags apply (ensure MessageComposerQuotedMessage passes its modifier
through to QuotedMessage).

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt`:
- Around line 262-269: The remember call that creates a QuotedMessageBodyBuilder
must include streamCdnImageResizing in its key list; update the remember
invocation (the one returning QuotedMessageBodyBuilder(resources,
autoTranslationEnabled, durationFormatter, streamCdnImageResizing)) to pass
streamCdnImageResizing alongside resources, autoTranslationEnabled, and
durationFormatter so the builder is recreated whenever streamCdnImageResizing
changes.
🧹 Nitpick comments (9)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt (1)

51-79: LGTM! Consider adding a preview.

The Row layout and UI elements are well-structured. Based on coding guidelines, Compose previews should use @StreamPreview helpers. Consider adding one for easier development iteration.

💡 Optional: Add a StreamPreview
`@StreamPreview`
`@Composable`
private fun MessageInputOptionsPreview() {
    ChatTheme {
        MessageInputOptions(
            activeAction = Edit(Message()),
            onCancelAction = {},
        )
    }
}
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt (2)

44-62: Consider using backtick test naming convention.

Per coding guidelines, test methods should use backtick names for readability. While the @ParameterizedTest(name = "{0}") provides descriptive test run names, the method itself could follow the convention:

-    fun testBuild(
+    fun `build returns expected QuotedMessageBody`(

64-74: Document the reason for suppressions.

Per coding guidelines, suppressions should be documented. Consider adding brief comments:

-    `@Suppress`("LargeClass")
+    `@Suppress`("LargeClass") // Contains comprehensive test data for all attachment types
     companion object {
         ...
         `@JvmStatic`
-        `@Suppress`("LongMethod")
+        `@Suppress`("LongMethod") // Parameterized test data covering all QuotedMessageBody scenarios
         fun attachmentTestCases() = listOf(
stream-chat-android-compose/api/stream-chat-android-compose.api (1)

3224-3226: ChatTheme(...) public API has an extremely long parameter list — consider a params object/builder to stabilize the surface.
Large, positional parameter lists are hard to use correctly and very costly to evolve; a dedicated ChatThemeParams (or builder DSL) tends to reduce future breaking changes and makes call sites self-documenting.

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt (1)

423-445: Good extraction of the trailing icon composable.

The refactoring improves readability by moving the inline Icon into a named composable. One minor accessibility consideration: contentDescription = null means screen readers won't announce the button's purpose. Consider providing a descriptive string like "Send message".

♻️ Suggested improvement for accessibility
             painter = painterResource(id = R.drawable.stream_compose_ic_send),
             tint = ChatTheme.colors.primaryAccent,
-            contentDescription = null,
+            contentDescription = "Send message",
         )
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt (2)

1759-1785: Public API change: document (and sanity-check) the new onCancel hook in MessageComposerInput.

  • KDoc above RowScope.MessageComposerInput doesn’t mention onCancel (Line 1772), and this is a public customization surface. As per coding guidelines, public APIs should be fully documented.
  • If you’re trying to minimize breaking changes for custom ChatComponentFactory implementations, consider a default (onCancel: () -> Unit = {}) and/or an overload that preserves the prior signature. As per coding guidelines, ...

126-126: Avoid name shadowing: MessageComposerQuotedMessage delegation is correct but fragile/unclear.

The method body relies on named arguments (message = …, currentUser = …) to resolve the imported io.getstream.chat.android.compose.ui.components.messages.MessageComposerQuotedMessage, not the factory method itself. This is easy to misread and can break if someone “simplifies” to positional args. Also, KDoc doesn’t mention onCancelClick.

Proposed clarity fix (alias the import)
-import io.getstream.chat.android.compose.ui.components.messages.MessageComposerQuotedMessage
+import io.getstream.chat.android.compose.ui.components.messages.MessageComposerQuotedMessage as DefaultMessageComposerQuotedMessage
@@
     public fun MessageComposerQuotedMessage(
         modifier: Modifier,
         state: MessageComposerState,
         quotedMessage: Message,
         onCancelClick: () -> Unit,
     ) {
-        MessageComposerQuotedMessage(
+        DefaultMessageComposerQuotedMessage(
             modifier = modifier,
             message = quotedMessage,
             currentUser = state.currentUser,
             onCancelClick = onCancelClick,
         )
     }

Also applies to: 1787-1810

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt (1)

25-120: StreamColors KDoc is now out of sync with the constructor (new semantic tokens are undocumented).

Please add @param docs for the new public fields (e.g., textPrimary, chatBgAttachmentIncoming/outgoing, chatReplyIndicatorIncoming/outgoing, chatTextMessage) so generated docs match the actual theming API. As per coding guidelines, ...

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (1)

175-287: Nice cohesion in the new internal rendering; please add snapshot coverage for regressions.

The extraction into small composables (QuotedMessageUserName, QuotedMessageText, QuotedMessageAttachmentPreview, etc.) makes the new design easier to reason about. Given this is a visual redesign, adding/refreshing Paparazzi snapshots for quoted/reply states would help prevent accidental regressions. Based on learnings, ...

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between af04cd9 and 08e62ef.

📒 Files selected for processing (35)
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/QuotedMessageAttachmentContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/messages/list/QuotedMessageStyle.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_camera.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_chart.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_file.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_link.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_map_pin.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_microphone.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_play_solid.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_video_outline.xml
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/util/DefaultQuotedMessageTextFormatterTest.kt
  • stream-chat-android-core/api/stream-chat-android-core.api
  • stream-chat-android-core/src/main/java/io/getstream/chat/android/models/AttachmentType.kt
  • stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/general/ChatTheme.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-ui-common/src/main/res/values/strings.xml
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/navigation/destinations/AttachmentDestination.kt
💤 Files with no reviewable changes (11)
  • stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/messages/list/QuotedMessageStyle.kt
  • stream-chat-android-core/api/stream-chat-android-core.api
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/util/DefaultQuotedMessageTextFormatterTest.kt
  • stream-chat-android-core/src/main/java/io/getstream/chat/android/models/AttachmentType.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/QuotedMessageAttachmentContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageContent.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/navigation/destinations/AttachmentDestination.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageText.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/general/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/QuotedMessageTextFormatter.kt
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{kt,kts}

📄 CodeRabbit inference engine (AGENTS.md)

Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)

Files:

  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/*.kt: Use @OptIn annotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes

Files:

  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
**/stream-chat-android-compose/**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/stream-chat-android-compose/**/*.kt: Compose components should follow noun-based naming (e.g., MessageList, ChannelListHeader)
Compose previews should use @StreamPreview helpers

Files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
**/src/test/**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/src/test/**/*.kt: Use backtick test names (for example: fun message list filters muted channels()) for readability
Use deterministic tests with runTest + virtual time for concurrency-sensitive logic (uploads, sync, message state)
Keep helper extensions private/internal in test files

Files:

  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
**/stream-chat-android-compose/**/*Test.kt

📄 CodeRabbit inference engine (AGENTS.md)

Add Paparazzi snapshots for Compose UI regressions and run verifyPaparazziDebug

Files:

  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
🧠 Learnings (6)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*Test.kt : Add Paparazzi snapshots for Compose UI regressions and run `verifyPaparazziDebug`

Applied to files:

  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_camera.xml
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_file.xml
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests

Applied to files:

  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_camera.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_play_solid.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_file.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_video_outline.xml
  • stream-chat-android-ui-common/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_chart.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_microphone.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*.kt : Compose previews should use `StreamPreview` helpers

Applied to files:

  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_camera.xml
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_file.xml
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_link.xml
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*.kt : Compose components should follow noun-based naming (e.g., `MessageList`, `ChannelListHeader`)

Applied to files:

  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/src/test/**/*.kt : Use backtick test names (for example: `fun `message list filters muted channels`()`) for readability

Applied to files:

  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/src/test/**/*.kt : Use deterministic tests with `runTest` + virtual time for concurrency-sensitive logic (uploads, sync, message state)

Applied to files:

  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt
🧬 Code graph analysis (3)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (3)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt (1)
  • rememberBodyBuilder (255-270)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/ComposerCancelIcon.kt (1)
  • ComposerCancelIcon (41-59)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/ImageUtils.kt (4)
  • StreamAsyncImage (113-128)
  • StreamAsyncImage (142-168)
  • StreamAsyncImage (182-197)
  • StreamAsyncImage (211-247)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt (1)
stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt (2)
  • randomPoll (866-908)
  • randomLocation (1132-1148)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (1)
  • MessageComposerQuotedMessage (149-172)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build / compose apks
  • GitHub Check: base-android-ci / Run unit tests
  • GitHub Check: base-android-ci / Run static checks
  • GitHub Check: base-android-ci / Build
  • GitHub Check: Detekt
  • GitHub Check: compare-sdk-sizes / Compare SDK sizes
🔇 Additional comments (23)
stream-chat-android-ui-common/src/main/res/values/strings.xml (1)

152-153: LGTM! Emoji prefixes removed from location strings.

The removal of the map pin emoji (📍) from both location labels aligns with the design update objective and provides cleaner, more accessible text. This is consistent with the broader effort to update UI presentation across the app.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInputOptions.kt (2)

35-42: LGTM!

The KDoc accurately reflects the updated behavior, documenting that this component now only renders for Edit actions.


49-49: Reply handling is properly covered in MessageInput component.

The if (activeAction !is Edit) return early return is intentional design. Reply actions are handled in MessageInput.kt (lines 105-110), where if (activeAction is Reply) triggers MessageComposerQuotedMessage rendering. The change is correct with no regression risk.

stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt (1)

146-146: LGTM!

The onCancelAction callback is correctly wired to dismiss message actions, aligning with the new API introduced in MessageInput for handling cancel events on quoted/reply messages.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt (1)

41-90: Well-structured builder consolidating quoted message logic.

The QuotedMessageBodyBuilder cleanly centralizes the rendering logic for quoted messages across various content types (deleted, poll, location, attachments). The cascading when expression provides clear precedence for different message states.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageTheme.kt (1)

112-114: Document the @Suppress("DEPRECATION_ERROR") suppression.

The annotation suppresses errors from accessing deprecated ERROR-level properties in StreamColors (ownMessagesBackground, otherMessagesBackground, deletedMessagesBackground, ownMessageText, otherMessageText). Per coding guidelines, avoid suppressions unless documented—add a KDoc comment explaining that this is intentional and necessary to access these deprecated but still-functional color properties during the migration to the new MessageTheme API.

stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilderTest.kt (2)

652-692: Well-structured mock helpers.

The mock setup is clean and correctly handles all the string and plural resources needed by the builder. Keeping these as private functions in the companion object follows the guidelines for test helper visibility.


74-650: Excellent test coverage.

The test cases comprehensively cover all attachment types, edge cases, and auto-translation scenarios. The parameterized approach with descriptive names makes it easy to identify which scenarios are being tested.

stream-chat-android-compose/api/stream-chat-android-compose.api (1)

2891-2902: No breaking change—MessageComposerInput and MessageComposerQuotedMessage have default implementations in the interface.

Custom ChatComponentFactory implementations are not forced to override these methods. Both methods already have default implementations in the ChatComponentFactory interface (see lines 1768–1785 and 1798–1810 in ChatComponentFactory.kt), so existing custom factories continue to work without modification.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_play_solid.xml (1)

1-25: LGTM!

Well-formed vector drawable with proper license header. The smaller 10x10dp size and solid white fill (vs. 12x12dp stroke-based icons elsewhere) is appropriate for a video thumbnail overlay indicator.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_link.xml (1)

1-32: LGTM!

Valid vector drawable with consistent styling (12x12dp, stroke color #384047, stroke width 1.2) matching the other icons in this PR. The clip-path and path structure correctly form the link icon.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_map_pin.xml (1)

1-34: LGTM!

Well-structured vector drawable with two paths forming the map pin icon. Consistent styling with other icons in the set.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_file.xml (1)

1-28: LGTM!

Clean vector drawable implementation with consistent styling. The path correctly renders a file icon with the characteristic folded corner.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_video_outline.xml (1)

1-34: LGTM!

Valid vector drawable with two paths forming the video camera outline. Maintains consistent styling with the other icons in this asset set.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_microphone.xml (1)

1-29: LGTM!

The vector drawable follows Android conventions with proper license header, matching dimensions/viewport, and appropriate stroke styling for the microphone icon.

stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_chart.xml (1)

1-29: LGTM!

The vector drawable follows Android conventions with proper license header and appropriate stroke styling for the chart icon. The square line caps are appropriate for the bar chart aesthetic.

stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt (2)

81-84: LGTM!

The documentation snippet correctly demonstrates the new onCancelAction handler, properly dismissing message actions from both the list and composer view models to ensure consistent UI state.


205-205: LGTM!

The customization snippet correctly wires onCancelAction to the MessageInput component, consistent with the new API surface.

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt (1)

394-397: LGTM!

The onCancelAction callback correctly dismisses message actions from both view models, ensuring the UI state is properly cleared when the user cancels a reply or edit action.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt (1)

105-111: LGTM on the wiring of onCancelAction.

The cancel action is correctly passed through to the MessageComposerQuotedMessage component, enabling users to dismiss the reply action from the quoted message UI.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt (1)

128-224: Defaults + new primitives look coherent; please verify contrast/spec for dark mode tokens.

The mapping of incoming/outgoing + reply indicator tokens to the new StreamPrimitiveColors reads consistent with the design-system intent, and keeping chatTextMessage defaulted from textPrimary is a nice simplification. I’d just sanity-check (visually) contrast for chatReplyIndicatorOutgoing = blue300 on chatBgOutgoing = blue800.

Also applies to: 228-246

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt (1)

47-52: Unusual member imports from ChatTheme: ensure these are intentional and don’t trip unused-import rules.

If these are only for KDoc symbol resolution, consider using fully-qualified references in KDoc instead of imports (depending on your lint setup).

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

172-183: onCancelAction propagation looks correct end-to-end.

Both composer entry points now thread onCancelAction into MessageInput (Line 180 / Line 327, then Line 602), which aligns with the new quoted-message cancel UX.

Also applies to: 321-331, 579-605

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@gpunto gpunto force-pushed the redesign/reply branch 5 times, most recently from 4e183e5 to f3c1b5f Compare January 15, 2026 15:24
@gpunto
Copy link
Contributor Author

gpunto commented Jan 15, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt (1)

294-341: Remove dead code: quotedDateAttachmentFactory and QuotedDateAttachmentContent are unused.

The Compose ChatTheme does not support a quotedAttachmentFactories parameter, so the quotedDateAttachmentFactory (lines 294-302) and QuotedDateAttachmentContent (lines 304-341) cannot be wired into the theme and have no effect. This pattern appears to be from the UI version, which has different customization APIs.

Remove this code snippet or update the documentation to explain how quoted message customization works in Compose (if supported).

stream-chat-android-compose/api/stream-chat-android-compose.api (1)

3585-3680: StreamColors has breaking changes requiring migration — comprehensive guidance is available in DEPRECATIONS.md.

The shape change is confirmed: Several deprecated properties (ownMessagesBackground, otherMessagesBackground, deletedMessagesBackground, ownMessageText, otherMessageText) are marked with @Deprecated(DeprecationLevel.ERROR) and replaced by MessageTheme properties. New design system semantic colors have been added (chatReplyIndicatorIncoming/Outgoing, chatBgAttachmentIncoming/Outgoing, textPrimary, borderCoreImage, controlRemoveBg, etc.).

Migration guidance already exists: See DEPRECATIONS.md for exact replacements and timelines, source code annotations for specific replacements, and factory methods defaultColors()/defaultDarkColors() for the complete new structure.

♻️ Duplicate comments (2)
stream-chat-android-compose/api/stream-chat-android-compose.api (2)

1644-1645: MessageInput(...) public signature change needs an explicit migration story (defaults/overload/docs).
Line 1644 shows the updated public API surface; if onCancelAction (or any new param) is now required or reordered, it’s a breaking change for downstream callers.


1812-1813: QuotedMessage(...) has two Message params — ensure Kotlin parameter names/order are unambiguous.
Line 1812 exposes two Lio/getstream/chat/android/models/Message; parameters; this is easy to misuse unless the Kotlin declaration uses clearly distinct names and a stable order (and ideally KDoc).

🧹 Nitpick comments (2)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (1)

262-276: Consider using a theme color for the play indicator background.

VideoPlayIndicator uses a hardcoded StreamPrimitiveColors.baseBlack instead of a theme-aware color. While a dark overlay is often intentional for video play buttons (for contrast), using a theme color would provide consistency if the design system evolves.

stream-chat-android-compose/api/stream-chat-android-compose.api (1)

3184-3186: ChatTheme(...) mega-signature churn: prefer “append-only with defaults” to reduce consumer breakage.
Line 3184 indicates a large surface-area signature; if parameters were reordered (not just added), expect significant downstream churn. If feasible in the Kotlin API, adding new params at the end with defaults (or providing overloads) is much easier to migrate.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 08e62ef and f3c1b5f.

⛔ Files ignored due to path filters (2)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_file_attachment_quoted_content.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.content_AttachmentsContentTest_media_attachment_quoted_content.png is excluded by !**/*.png
📒 Files selected for processing (14)
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/StreamAttachmentFactories.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/AudioRecordAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/FileAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/MediaAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/factory/QuotedAttachmentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/general/CustomAttachments.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt
  • stream-chat-android-ui-guides/src/main/java/io/getstream/chat/android/guides/catalog/compose/customattachments/MessagesActivity.kt
💤 Files with no reviewable changes (8)
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/general/CustomAttachments.kt
  • stream-chat-android-ui-guides/src/main/java/io/getstream/chat/android/guides/catalog/compose/customattachments/MessagesActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/AudioRecordAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/attachments/content/AttachmentsContentTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/factory/QuotedAttachmentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/FileAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/MediaAttachmentQuotedContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/StreamAttachmentFactories.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,kts}

📄 CodeRabbit inference engine (AGENTS.md)

Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)

Files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/*.kt: Use @OptIn annotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes

Files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
**/stream-chat-android-compose/**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/stream-chat-android-compose/**/*.kt: Compose components should follow noun-based naming (e.g., MessageList, ChannelListHeader)
Compose previews should use @StreamPreview helpers

Files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
🧠 Learnings (5)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*.kt : Compose previews should use `StreamPreview` helpers

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*.kt : Compose components should follow noun-based naming (e.g., `MessageList`, `ChannelListHeader`)

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*Test.kt : Add Paparazzi snapshots for Compose UI regressions and run `verifyPaparazziDebug`

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
📚 Learning: 2026-01-15T13:09:56.922Z
Learnt from: gpunto
Repo: GetStream/stream-chat-android PR: 6084
File: stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_camera.xml:27-28
Timestamp: 2026-01-15T13:09:56.922Z
Learning: In stream-chat-android-compose, drawable XML icon files (e.g., stream_compose_ic_*.xml) use hardcoded placeholder colors because tint is applied programmatically when the icons are used in composables, ensuring theme-aware coloring at runtime.

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt
  • stream-chat-android-compose/api/stream-chat-android-compose.api
🧬 Code graph analysis (2)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (3)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt (1)
  • rememberBodyBuilder (255-270)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/ComposerCancelIcon.kt (1)
  • ComposerCancelIcon (41-59)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/ImageUtils.kt (4)
  • StreamAsyncImage (113-128)
  • StreamAsyncImage (142-168)
  • StreamAsyncImage (182-197)
  • StreamAsyncImage (211-247)
stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/guides/AddingCustomAttachments.kt (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt (1)
  • ChatTheme (315-479)
🔇 Additional comments (10)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt (1)

314-412: LGTM! Clean removal of quoted-message theming parameters.

The removal of quotedAttachmentFactories and quotedMessageTextFormatter parameters from ChatTheme aligns with the PR objective to consolidate quoted-message rendering logic into the new QuotedMessageBodyBuilder. The function signature is cleaner, and all composition locals are properly maintained.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessage.kt (2)

131-132: LGTM! Properly keyed remember for body builder.

The remember call now correctly includes bodyBuilder in its keys, ensuring the body is recomputed when theme settings change. This addresses the previous review feedback.


156-170: LGTM! Modifier is now properly applied.

The modifier parameter is now correctly passed to Box(modifier), allowing callers to style and tag the component. This addresses the previous review feedback.

stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/messages/QuotedMessageBodyBuilder.kt (2)

255-270: LGTM! All dependencies properly included in remember keys.

The rememberBodyBuilder() composable now correctly includes all four dependencies (resources, autoTranslationEnabled, durationFormatter, streamCdnImageResizing) in the remember keys, ensuring the builder is recreated when any configuration changes. This addresses the previous review feedback.


42-90: Well-structured builder with clear precedence logic.

The build() method has a clean precedence order: deleted messages → polls → shared locations → attachments → plain text. The translation handling is correctly applied early in the flow. Good separation of concerns.

stream-chat-android-compose/src/main/res/values/strings.xml (2)

102-109: LGTM! Consistent singular forms for images and videos.

The plurals for stream_compose_quoted_message_images and stream_compose_quoted_message_videos now use consistent patterns:

  • Singular: "Photo" / "Video" (no count)
  • Plural: "%d photos" / "%d videos"

This addresses the previous review feedback about inconsistent singular forms.


92-96: New quoted message strings look good.

The new strings for audio recording, media count, reply-to formatting, and "You" label are clear and well-structured for the updated quoted message design.

stream-chat-android-compose/api/stream-chat-android-compose.api (3)

2852-2863: Keep ChatComponentFactory.MessageComposerInput / MessageComposerQuotedMessage parameter ordering aligned with MessageInput to avoid wiring bugs.
Lines 2852-2853 and 2862-2863 suggest new/shifted callbacks; please double-check the Kotlin implementations/wrappers pass the correct lambda to the correct slot (especially around “cancel” vs other composer actions).


3034-3045: Confirm ChatComponentFactory$DefaultImpls matches the interface after the signature change.
Lines 3034-3035 and 3044-3045 are the generated defaults for the updated interface methods; worth verifying there’s no accidental mismatch that could surface as confusing binary/API behavior for implementers.


3504-3538: Verify the specific parameter order changes and binary compatibility implications.

MessageTheme.kt was modified in the current commit. However, the breaking change claim requires clarification: confirm whether parameters were reordered (breaking Kotlin destructuring) or merely appended with defaults (backward-compatible). The CHANGELOG documents incremental property additions, and DEPRECATIONS.md properly handles StreamColors.linkBackground. Release notes should document any actual breaking changes versus API expansions.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@gpunto gpunto marked this pull request as ready for review January 16, 2026 08:48
@gpunto gpunto requested a review from a team as a code owner January 16, 2026 08:48
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

modifier = Modifier.weight(1f, fill = false),
currentUser = currentUser,
)
private fun QuotedMessageAttachmentPreview(body: QuotedMessageBody) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems the location preview is missing.
Image
There's a thread in the Figma file about whether the preview should be a real map or just a placeholder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that we were leaving this preview out for now based on the thread, but maybe I misunderstood 🤔 Should I just add the placeholder image?

val customFactories = listOf(dateAttachmentFactory)
val defaultFactories = StreamAttachmentFactories.defaults()

val customQuotedFactories = listOf(quotedDateAttachmentFactory)
Copy link
Contributor

Choose a reason for hiding this comment

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

How can customers handle custom attachments?
Maybe you could show an example in this file?

Copy link
Contributor Author

@gpunto gpunto Jan 19, 2026

Choose a reason for hiding this comment

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

Good point. At the moment they would need to replace the QuotedMessage/ComposerQuotedMessage in the factory. I'll check what iOS/Flutter provide, see if we need to change anything and then add an example!

Copy link
Contributor Author

@gpunto gpunto Jan 19, 2026

Choose a reason for hiding this comment

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

So, it seems that iOS follows the generic pattern of using the view factory for that. So we could adapt and do the same on our side. It makes sense to me, not only to align with iOS, but also to align internally: custom rendering for other components goes through the factory, so I don't think there's a compelling reason to handle attachments in a different way. The downside is that it of course increases the number of breaking changes.

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that's the current iOS way to customize attachments.
Is that how the SDKs should proceed? Or are we agreeing on replacing QuotedMessage/ComposerQuotedMessage components?

Copy link
Contributor

@andremion andremion left a comment

Choose a reason for hiding this comment

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

location placeholder and custom factories to be addressed in another PR 👍🏻

@gpunto gpunto merged commit 088bc3f into v7 Jan 20, 2026
17 of 19 checks passed
@gpunto gpunto deleted the redesign/reply branch January 20, 2026 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants