Skip to content

Conversation

@gpunto
Copy link
Contributor

@gpunto gpunto commented Jan 2, 2026

🎯 Goal

AND-996: Update composer link preview design

Adapt design of the component displaying link previews in the composer.

🛠 Implementation details

  • Move display of the link previews from above to inside the message input
  • Update ComposerLinkPreview and CancelIcon to new design

🎨 UI Changes

Figma: https://www.figma.com/design/Us73erK1xFNcB5EH3hyq6Y/%F0%9F%9A%A7-Chat-SDK-Design-System?node-id=322-9605

Note: given that the rest of the composer design isn't yet update, the complete result isn't perfect, e.g.:

  • the preview feels crammed because there's less horizontal space than in the final design and vertical padding is still to adjust
  • the cancel icon border doesn't blend into the background
Before After
Screenshot_20260102_165750 Screenshot_20260102_165710

🧪 Testing

Launch the compose sample, open a chat and add a link in the composer

☑️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

    • Added link preview click handling to the message composer, allowing users to interact with previewed links.
  • Style

    • Enhanced link preview appearance with borders, backgrounds, and rounded corners.
    • Added border styling to the message composer's cancel icon.
    • Refined attachment shape corners for improved visual consistency.
    • Expanded design system with new semantic colors for borders and controls.

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

@gpunto gpunto force-pushed the redesign/composer-link-preview branch 2 times, most recently from 44bc7de to b6767c2 Compare January 2, 2026 16:14
@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 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.60 MB 10.60 MB 0.00 MB 🟢
stream-chat-android-compose 12.81 MB 11.66 MB -1.15 MB 🚀

@gpunto gpunto force-pushed the redesign/composer-link-preview branch 2 times, most recently from fa4ff88 to 4242237 Compare January 2, 2026 16:27
@Deprecated("Use MessageTheme.quotedTextStyle.color instead", level = DeprecationLevel.ERROR)
public val otherMessageQuotedText: Color = textHighEmphasis,

// Design System semantic colors
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The objective is to end up with none of the already-existing colors above and just have the semantic colors as defined in Figma. Hopefully they'll be autogenerated too. Similarly for StreamPrimitiveColors below

@@ -112,9 +116,10 @@ public data class ComposerCancelIconStyle(
): ComposerCancelIconStyle {
return ComposerCancelIconStyle(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now, I changed the existing styles to adapt them to the new designs. However, I'd really love if we could simplify/remove them altogether as they add complexity just to allow very granular customization of really simple components. To me, it would make more sense for an integrator to just replace the component in such simple cases.

I'll discuss this next week with the rest of the folks working on the redesign

messageComposerState: MessageComposerState,
onValueChange: (String) -> Unit,
onAttachmentRemoved: (Attachment) -> Unit,
onLinkPreviewClick: ((LinkPreview) -> Unit)?,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In new design, the message input gains more components to be displayed above the actual input, like the link preview in this PR. For the time being, I've just put the invocation of the link preview inside the input itself below and added this callback here, like it already works for quoted message & attachments.

However, later we may consider if it's worth changing the approach and expose a @Composable slot here for what goes above the input and then we pass a column with the default composables we want.

@gpunto gpunto force-pushed the redesign/composer-link-preview branch 3 times, most recently from 3b05032 to 5992f07 Compare January 5, 2026 09:58
@gpunto gpunto marked this pull request as ready for review January 5, 2026 09:58
@gpunto gpunto requested a review from a team as a code owner January 5, 2026 09:58
@gpunto gpunto force-pushed the redesign/composer-link-preview branch from 5992f07 to 665e3af Compare January 5, 2026 10:13
@gpunto
Copy link
Contributor Author

gpunto commented Jan 5, 2026

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 5, 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 5, 2026

Walkthrough

This PR refactors the message composer's link preview functionality and styling. It introduces a new onLinkPreviewClick callback parameter throughout the composer pipeline, redesigns the link preview UI layout, enhances visual styling with borders and semantic colors, and implements centralized click handling for link previews.

Changes

Cohort / File(s) Summary
Link Preview Click Handling
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt, MessageComposer.kt, ChatComponentFactory.kt
Added onLinkPreviewClick: ((LinkPreview) -> Unit)? parameter across message composer APIs and wired it to link preview rendering. MessageInput now conditionally renders MessageComposerLinkPreview with the callback when link previews exist and feature is enabled.
Link Preview Click Handling (Testing)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.kt
Added unit tests for handleLinkPreviewClick function covering callback delegation and fallback ACTION_VIEW intent behavior.
Link Preview UI Refactor
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
Major redesign from Row-based to Box-based layout with dedicated text composables, centralized click handling via new internal handleLinkPreviewClick function, URL resolution via extension, and CancelIcon integration. ComposerLinkPreview marked internal; error handling added for ACTION_VIEW intent failures.
Cancel Icon Styling
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
Reworked to derive all visual properties (border, shape, background, painter, tint) from style object instead of direct theme usage. Added conditional border application via Modifier.border and fixed 2.dp padding.
Composer Theme Updates
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
ComposerCancelIconStyle now includes border: BorderStroke? parameter and cross painter. ComposerLinkPreviewTheme restructured with background, shape, imageBorder, url styling; removed separator properties. Default theme factory signature expanded to accept shapes: StreamShapes.
Color System Expansion
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
Added semantic design colors: borderCoreOnDark, borderCoreImage, chatBgIncoming, chatBgOutgoing, controlRemoveBg, controlRemoveBorder, controlRemoveIcon. New internal StreamPrimitiveColors object provides palette foundation.
Shape Adjustments
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamShapes.kt
Changed default attachment shape corner radius from 16.dp to 12.dp.
Vector Assets
stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_cross.xml
New cross icon drawable (16x16dp, white stroke, round caps) for cancel/close actions.
API Declarations
stream-chat-android-compose/api/stream-chat-android-compose.api
Updated public signatures for MessageInput, ComposerCancelIconStyle, ComposerLinkPreviewTheme, StreamColors, and related theme classes. Added new ComposableSingletons class. Expanded constructor and copy method signatures.
Documentation & Samples
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.kt, stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt, CustomComposerAndAttachmentsPicker.kt
Updated sample and documentation code to pass onLinkPreviewClick = null to MessageInput. Removed explicit attachmentCancelIcon customization.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MessageInput as MessageInput<br/>(Composable)
    participant ComposerLP as ComposerLinkPreview<br/>(Composable)
    participant Handler as handleLinkPreviewClick<br/>(Function)
    participant Callback as onLinkPreviewClick<br/>(Optional Callback)
    participant Context as Context/<br/>Activity
    
    User->>ComposerLP: clicks link preview
    ComposerLP->>Handler: invokes with onClick callback
    
    alt onClick callback provided
        Handler->>Callback: invokes onClick(linkPreview)
        Callback-->>User: handles click
    else onClick is null (default)
        Handler->>Context: startActivity with ACTION_VIEW intent
        Note over Handler: logs and toasts on error
        Context-->>User: opens URL in browser
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 A hop through the preview so fine,
New borders and shapes all align,
From click to callback it flows,
Where each link preview glows,
With colors semantic—a designer's design! 🎨✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update design of composer link preview' directly and clearly summarizes the main change: updating the visual design of the composer link preview component.
Description check ✅ Passed The description includes the required sections (Goal, Implementation details, UI Changes with before/after screenshots, and Testing), though the Contributor Checklist items remain unchecked.
Linked Issues check ✅ Passed The PR implements AND-996 objectives: it updates ComposerLinkPreview and CancelIcon design, moves link preview display into the message input, and provides UI changes with Figma reference and screenshots.
Out of Scope Changes check ✅ Passed All changes are scoped to the AND-996 objective: ComposerLinkPreview redesign, CancelIcon styling, link preview placement in MessageInput, theme updates, and supporting test coverage.
✨ 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: 3

Fix all issues with AI Agents 🤖
In @stream-chat-android-compose/api/stream-chat-android-compose.api:
- Line 1687: The new onLinkPreviewClick parameter was inserted before modifier
in MessageInput and ChatComponentFactory.MessageComposerInput breaking
source/binary compatibility; move the onLinkPreviewClick parameter to the end of
each function’s parameter list (after innerTrailingContent) and keep its default
value ((LinkPreview) -> Unit)? = null so existing positional callers continue to
work, then update any corresponding overloads/signatures and generated API
metadata to reflect the new parameter order.

In
@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt:
- Around line 70-76: Replace the standard Compose preview annotation with the
project's preview helper: change the CancelIconPreview function's annotation
from @Preview to @StreamPreview so the preview follows project guidelines;
update the annotation above the CancelIconPreview composable (which calls
CancelIcon) accordingly.

In
@stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt:
- Line 45: Remove the unused import OnlineIndicator from the top of the file;
locate the import statement "import
io.getstream.chat.android.compose.ui.components.OnlineIndicator" in
CustomComposerAndAttachmentsPicker.kt and delete that line so there are no
unused imports remaining.
🧹 Nitpick comments (6)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.kt (1)

28-59: Consider adding edge case tests.

The tests cover the main happy paths well. Consider adding tests for:

  1. ActivityNotFoundException handling (toast displayed, error logged)
  2. Null URL scenario (when both titleLink and ogUrl are null) to verify the checkNotNull behavior

These would improve coverage of error handling paths in handleLinkPreviewClick.

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

211-217: Consider using @StreamPreview helper.

Per coding guidelines, Compose previews should use StreamPreview helpers instead of the standard @Preview annotation for consistency across the SDK.

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

3709-3757: StreamColors growth is acceptable but getting unwieldy; consider future grouping

You’ve extended StreamColors with several new fields (e.g., borderCoreImage, borderCoreOnDark, chatBgIncoming, chatBgOutgoing, and the controlRemove* colors). This is a reasonable way to support the updated composer/link‑preview visuals from the design system, and the constructor/copy/getter set appears consistent.

However, the constructor and copy(...) for StreamColors are now extremely long and increasingly hard to maintain without mistakes.

For this PR, I’d just suggest:

  • Double‑check that defaultColors / defaultDarkColors initialize all new fields coherently and that the new colors are actually consumed by the new composer/link‑preview components.
  • Longer term, consider grouping related colors into smaller value objects (e.g., a ComposerColors or BorderColors struct) to keep the API surface from becoming too error‑prone to evolve.

Also applies to: 3760-3767

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

117-125: New semantic colors added without KDoc documentation.

The new design system colors (borderCoreOnDark, borderCoreImage, chatBgIncoming, chatBgOutgoing, controlRemoveBg, controlRemoveBorder, controlRemoveIcon) are public API but lack documentation in the class-level KDoc. Consider adding @param entries to maintain documentation consistency with existing properties.


214-219: Consider explicitly setting controlRemoveBorder for clarity.

Unlike defaultColors() which explicitly sets controlRemoveBorder, this relies on the default value. While functionally equivalent (both resolve to baseWhite), explicit initialization would improve readability and make the dark theme configuration self-documenting.

Suggested change
 controlRemoveBg = StreamPrimitiveColors.neutral800,
 controlRemoveIcon = StreamPrimitiveColors.baseWhite,
+controlRemoveBorder = StreamPrimitiveColors.baseWhite,
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt (1)

410-426: Unused onLinkPreviewClick parameter in DefaultMessageComposerHeaderContent.

The onLinkPreviewClick parameter is added to the function signature but not used in the implementation body. Since link previews have been moved to the input area, consider either:

  1. Removing this parameter if it's not needed for API compatibility
  2. Adding a clarifying comment if it's kept intentionally for custom implementations
📜 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 bf3e3d1 and 24cee0b.

📒 Files selected for processing (14)
  • 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/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.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/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.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/StreamShapes.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_cross.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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
🧰 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-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/MessageInput.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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/ChatComponentFactory.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/StreamShapes.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.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/composer/MessageInput.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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/ChatComponentFactory.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/StreamShapes.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/MessagesActivity.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/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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/ChatComponentFactory.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/StreamShapes.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.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/composer/HandleLinkPreviewClickTest.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/composer/HandleLinkPreviewClickTest.kt
🧠 Learnings (6)
📓 Common learnings
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
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`
📚 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/composer/MessageInput.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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/ChatComponentFactory.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/StreamShapes.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
  • 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
📚 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/composer/MessageInput.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.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/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
  • 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
📚 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/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/theme/ChatComponentFactory.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/composer/MessageComposer.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.kt
  • 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
📚 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_cross.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamColors.kt
  • stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/cookbook/ui/CustomComposerAndAttachmentsPicker.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/MessageComposerTheme.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: Keep Compose and XML UI kits behaviourally aligned; update shared fixtures/tests when touching one side

Applied to files:

  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt
🧬 Code graph analysis (4)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/composer/HandleLinkPreviewClickTest.kt (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt (1)
  • handleLinkPreviewClick (181-207)
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/messages/composer/MessageComposer.kt (1)
  • DefaultComposerInputContent (576-601)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/composer/ComposerLinkPreview.kt (2)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt (1)
  • CancelIcon (39-68)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/util/ImageUtils.kt (4)
  • StreamAsyncImage (122-137)
  • StreamAsyncImage (151-177)
  • StreamAsyncImage (191-206)
  • StreamAsyncImage (220-256)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/CancelIcon.kt (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatTheme.kt (1)
  • ChatTheme (320-496)
⏰ 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: base-android-ci / Run static checks
  • GitHub Check: Build / compose apks
  • GitHub Check: base-android-ci / Run unit tests
  • GitHub Check: base-android-ci / Build
  • GitHub Check: compare-sdk-sizes / Compare SDK sizes
  • GitHub Check: Detekt
🔇 Additional comments (24)
stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/compose/messages/MessageComposer.kt (1)

205-205: LGTM!

The addition of onLinkPreviewClick = null correctly demonstrates the new API parameter in the customization example. Using null appropriately triggers the default browser navigation behavior.

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

67-67: Visual breaking change: attachment corner radius reduced.

The default attachment shape corner radius changed from 16dp to 12dp. This affects all consumers using the default theme. Confirm this aligns with the new Chat SDK Design System specifications.

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

85-88: LGTM on the public API design.

The nullable onClick parameter with default null provides good flexibility - consumers can either provide a custom handler or rely on the default browser navigation. The function signature is clean and well-documented.


181-207: Well-structured click handling with proper error recovery.

The handleLinkPreviewClick function has good separation of concerns:

  • Custom handler takes precedence when provided
  • Default browser navigation with scheme normalization
  • ActivityNotFoundException is caught with user-friendly toast feedback

The checkNotNull assertion is appropriate here since a link preview without a URL represents a programming error.


145-159: Clean image preview implementation.

The ComposerLinkImagePreview properly delegates to theme-based styling for dimensions, shape, and border. The early return on null imagePreviewUrl is a good defensive pattern.


161-172: LGTM!

The ComposerLinkPreviewText helper effectively reduces code duplication and provides consistent text rendering with proper test tag support.


100-142: Well-structured layout with proper cancel icon positioning.

The Box wrapper with CancelIcon using offset positioning is a clean approach for the overlapping cancel button design. The Row layout with theme-based styling and proper spacing is well-organized.

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

1369-1374: New ComposableSingletons$CancelIconKt follows existing Compose singleton pattern

The added singleton and backing lambda field are consistent with the other ComposableSingletons$* classes generated by Compose and don’t expand the manual API surface beyond what you already expose elsewhere in this module. No issues here.


3360-3368: Composer theming expansions (cancel icon + link preview) look coherent with the design goal

The changes to:

  • ComposerCancelIconStyle (adding BorderStroke, icon painter, and tint), and
  • ComposerLinkPreviewTheme (background shape, image size/shape/border, title/subtitle/url TextComponentStyle, embedded ComposerCancelIconStyle, and an updated defaultTheme taking StreamShapes)

together with MessageComposerTheme now holding these richer theme objects, give a clean, centralized way to style the redesigned link preview and cancel icon.

From the API surface, the field ordering, component*/copy* signatures, and getters look internally consistent and aligned with the rest of your theming model; no obvious correctness issues here.

It’d be good to quickly verify that ComposerLinkPreviewTheme.Companion.defaultTheme(...) uses the new StreamShapes/StreamColors slots to match the Figma spec (e.g., image corner radii and border color) so the default theme truly reflects the intended design.

Also applies to: 3371-3375, 3411-3443, 3510-3533

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

147-147: LGTM!

The addition of onLinkPreviewClick = null correctly integrates with the new link preview callback parameter introduced in this PR.

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

1-28: LGTM!

The cross icon drawable is well-defined with appropriate dimensions and styling. The white stroke color is suitable for use on dark backgrounds as seen in the cancel icon implementation.

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

394-394: LGTM!

The addition of onLinkPreviewClick = null correctly adopts the new API. Setting it to null means link previews in this custom composer will use the default behavior (launching an ACTION_VIEW intent as per the test file HandleLinkPreviewClickTest.kt).

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

1767-1782: LGTM!

The addition of the onLinkPreviewClick parameter to MessageComposerInput correctly extends the public API to support link preview interactions. The parameter is appropriately typed as a nullable callback and is properly propagated to DefaultComposerInputContent.

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

44-67: LGTM!

The refactoring to use a style object (ChatTheme.messageComposerTheme.attachmentCancelIcon) for all visual properties (border, backgroundShape, backgroundColor, painter, tint) improves maintainability and enables consistent theming across the SDK. The conditional border application is correctly implemented.

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

69-83: LGTM - Public API extended with link preview click handler.

The new onLinkPreviewClick parameter is properly nullable for optional behavior and positioned appropriately among the other callback parameters. The existing KDoc should be updated to document this new parameter.

Suggested KDoc addition

Add to the KDoc block above the function:

 * @param onLinkPreviewClick Handler when the user taps on a link preview, or null to disable click handling.

115-121: LGTM - Link preview rendering is correctly guarded.

The feature flag check and non-empty validation ensure safe access to linkPreviews.first(). Only displaying the first preview is a reasonable design choice for the composer.


146-165: Good extraction of AttachmentPreview into a separate composable.

This improves readability and follows the single-responsibility principle. The null-safe invocation chain correctly handles cases where no suitable factory is found.

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

167-173: LGTM - Light mode semantic colors correctly initialized.

The new semantic colors are properly initialized using StreamPrimitiveColors values, providing a consistent light theme palette.


224-233: LGTM - Well-structured primitive colors foundation.

The internal visibility appropriately restricts access to this implementation detail, and the @Suppress("MagicNumber") is correctly applied for hex color literals.

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

116-138: LGTM - Consistent threading of onLinkPreviewClick callback.

The new parameter is properly integrated into the ViewModel-based MessageComposer overload and correctly propagated to both headerContent and input lambdas.


575-601: LGTM - Input content correctly updated with link preview click handling.

The @Suppress("LongParameterList") is appropriate for this internal function with many parameters. The onLinkPreviewClick callback is correctly wired through to MessageInput.

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

74-83: LGTM - Theme factory correctly updated to pass shapes.

The addition of shapes parameter to ComposerLinkPreviewTheme.defaultTheme call aligns with the expanded theming capabilities.


96-125: LGTM - Cancel icon style enhanced with border support.

The nullable border property provides flexibility for customization. The use of semantic colors (controlRemoveBg, controlRemoveBorder, controlRemoveIcon) aligns well with the design system approach. KDoc is properly documented, and the drawable resource stream_compose_ic_cross exists as referenced.


143-197: Remove unnecessary @Suppress("DEPRECATION_ERROR") annotation on defaultTheme() function.

The suppression on line 158 is not needed. The properties used in this function—chatBgOutgoing, borderCoreImage, and textHighEmphasis—are not deprecated. This suppression appears to have been copy-pasted from other theme functions like MessageTheme.defaultTheme() which do use deprecated error-level properties. Per coding guidelines, suppressions must be avoided unless documented; this one should be removed entirely.

Likely an incorrect or invalid review comment.

@gpunto gpunto force-pushed the redesign/composer-link-preview branch from 24cee0b to f55f6d7 Compare January 5, 2026 12:33
@gpunto gpunto force-pushed the redesign/composer-link-preview branch from 6b65d45 to 6b4556f Compare January 5, 2026 14:37
@gpunto gpunto marked this pull request as draft January 8, 2026 16:17
@gpunto gpunto force-pushed the redesign/composer-link-preview branch from f896513 to b27d172 Compare January 8, 2026 16:49
@gpunto gpunto marked this pull request as ready for review January 12, 2026 12:12
@sonarqubecloud
Copy link

@gpunto gpunto requested a review from VelikovPetar January 12, 2026 12:38
@gpunto gpunto merged commit ef54d03 into v7 Jan 13, 2026
14 checks passed
@gpunto gpunto deleted the redesign/composer-link-preview branch January 13, 2026 10:53
@coderabbitai coderabbitai bot mentioned this pull request Jan 15, 2026
16 tasks
@gpunto gpunto mentioned this pull request Jan 16, 2026
16 tasks
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