Skip to content

Use type-specific attachment URL fields and deprecate imagePreviewUrl#6280

Merged
andremion merged 3 commits intodevelopfrom
bug/AND-1126_use_correct_image_urls
Mar 26, 2026
Merged

Use type-specific attachment URL fields and deprecate imagePreviewUrl#6280
andremion merged 3 commits intodevelopfrom
bug/AND-1126_use_correct_image_urls

Conversation

@VelikovPetar
Copy link
Copy Markdown
Contributor

@VelikovPetar VelikovPetar commented Mar 23, 2026

Goal

We were incorrectly prioritising thumb_url over image_url for image attachments. This was not visible on the sample, because the default Stream CDN, doesn't generate thumb_url for image uploads. However customer CDN which create thumbnails for images, were incorrectly prioritising the thumbnail (which can be lower resolution for example).
In the PR, we are explicitly using image_url for images, and thumb_url for other attachments where the field is relevant. (Additionally, aligns the logic with the SwiftUI SDK)

Implementation

  • Deprecate imagePreviewUrl in Attachment.kt with @Deprecated(WARNING) — preserves backward compatibility for external callers
  • Migrate all ~20 internal call sites across Compose, XML UI, samples, and ViewModels:
    • Image attachmentsimageUrl (aligns with iOS imageURL)
    • Video thumbnailsthumbUrl (aligns with iOS thumbnailURL)
    • Link previewsthumbUrl ?: imageUrl (aligns with iOS previewURL decoded from thumb_url with fallback to assetURL)
    • GiphythumbUrl via giphyInfo?.url fallback chain (aligns with iOS previewURL)
  • Update imagePreviewData Compose extension to branch on isImage() vs isVideo() instead of using the deprecated property
  • Add unit tests for the deprecated imagePreviewUrl property

UI Changes

There should be now changes in the existing behaviour. (given the fact that thumb_url is null for images from Stream CDN)

Testing

  • Manual testing: verify image display, video thumbnails, link previews, giphy, quoted messages, full-screen gallery, composer preview, and channel media grid

Summary by CodeRabbit

  • Deprecations

    • Marked Attachment.imagePreviewUrl as deprecated; use attachment-type-specific fields (imageUrl for images, thumbUrl for videos/previews) instead.
  • Breaking Changes

    • Updated gallery fragment factory APIs to accept explicit URL parameters instead of full attachment objects.
  • Improvements

    • Enhanced image and video attachment preview handling by using more appropriate source fields based on attachment type.
  • Tests

    • Added test coverage for imagePreviewUrl behavior.

Co-Authored-By: Claude <noreply@anthropic.com>
@VelikovPetar VelikovPetar added the pr:bug Bug fix label Mar 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 23, 2026

PR checklist ✅

All required conditions are satisfied:

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

🎉 Great job! This PR is ready for review.

@VelikovPetar VelikovPetar changed the title Deprecate imagePreviewUrl and use type-specific attachment URL fields Use type-specific attachment URL fields and deprecate imagePreviewUrl Mar 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 23, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.26 MB 5.26 MB 0.00 MB 🟢
stream-chat-android-offline 5.49 MB 5.49 MB 0.00 MB 🟢
stream-chat-android-ui-components 10.63 MB 10.63 MB 0.00 MB 🟢
stream-chat-android-compose 12.86 MB 12.86 MB 0.00 MB 🟢

@VelikovPetar VelikovPetar marked this pull request as ready for review March 23, 2026 09:00
@VelikovPetar VelikovPetar requested a review from a team as a code owner March 23, 2026 09:00
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 23, 2026

Walkthrough

This pull request systematically deprecates the Attachment.imagePreviewUrl extension property and replaces its usages across the codebase with direct references to more specific attachment fields (imageUrl, thumbUrl, assetUrl) based on context. The extension is marked with a @Deprecated warning, and some factory method signatures are updated to accept explicit URL parameters instead of Attachment objects.

Changes

Cohort / File(s) Summary
Deprecation & Test Coverage
stream-chat-android-ui-common/src/main/kotlin/.../Attachment.kt, stream-chat-android-ui-common/src/test/kotlin/.../AttachmentExtensionsTest.kt
Added @Deprecated annotation (warning level) to Attachment.imagePreviewUrl with migration guidance. New test class validates the property's behavior across thumbUrl/imageUrl combinations.
Compose Sample Apps
stream-chat-android-compose-sample/src/main/java/.../ChannelMediaAttachmentsActivity.kt, stream-chat-android-compose-sample/src/main/java/.../ChatsActivity.kt
Updated localFilter logic in ChannelAttachmentsViewModelFactory to check (imageUrl ?: thumbUrl) instead of imagePreviewUrl.
Compose Attachment Content Components
stream-chat-android-compose/src/main/java/.../ImageAttachmentPreviewContent.kt, stream-chat-android-compose/src/main/java/.../LinkAttachmentContent.kt, stream-chat-android-compose/src/main/java/.../MediaAttachmentPreviewContent.kt, stream-chat-android-compose/src/main/java/.../MediaAttachmentQuotedContent.kt
Replaced imagePreviewUrl with attachment-type-specific fallbacks: imageUrl for images, thumbUrl for video thumbnails, and conditional selection based on isImage()/isVideo() checks.
Compose Core Utilities
stream-chat-android-compose/src/main/java/.../AttachmentExtensions.kt, stream-chat-android-compose/src/main/java/.../MediaGalleryPage.kt, stream-chat-android-compose/src/main/java/.../ChannelMediaAttachmentsScreen.kt, stream-chat-android-compose/src/main/java/.../ComposerLinkPreview.kt
Updated imagePreviewData property to use type-specific URL selection (images use imageUrl, videos use thumbUrl). Preview components now derive URLs based on attachment type.
ViewModel Logging
stream-chat-android-compose/src/main/java/.../ChannelMediaAttachmentsPreviewViewModel.kt
Updated debug logging to reference imageUrl and thumbUrl instead of deprecated imagePreviewUrl.
UI Components Gallery & Fragment Factory
stream-chat-android-ui-components/src/main/kotlin/.../AttachmentGalleryImagePageFragment.kt, stream-chat-android-ui-components/src/main/kotlin/.../AttachmentGalleryVideoPageFragment.kt, stream-chat-android-ui-components/src/main/kotlin/.../AttachmentGalleryPagerAdapter.kt
Breaking API changes: Fragment factory methods now accept explicit imageUrl/thumbUrl/assetUrl parameters instead of Attachment objects. Adapter updated to pass specific URL fields when creating fragments.
UI Components Attachment Views
stream-chat-android-ui-components/src/main/kotlin/.../MediaAttachmentAdapter.kt, stream-chat-android-ui-components/src/main/kotlin/.../DefaultQuotedAttachmentView.kt, stream-chat-android-ui-components/src/main/kotlin/.../LinkAttachmentView.kt, stream-chat-android-ui-components/src/main/kotlin/.../MediaAttachmentView.kt, stream-chat-android-ui-components/src/main/kotlin/.../GiphyMediaAttachmentView.kt, stream-chat-android-ui-components/src/main/kotlin/.../GiphyViewHolder.kt
Replaced imagePreviewUrl usage with conditional logic: imageUrl for images, thumbUrl ?: imageUrl for links/Giphy, and thumbUrl for video thumbnails.
Message List View
stream-chat-android-ui-components/src/main/kotlin/.../MessageListView.kt
Updated Giphy URL fallback chain and image gallery filtering to use thumbUrl/imageUrl instead of imagePreviewUrl. Removed large block of unused imports.
UI Components Sample
stream-chat-android-ui-components-sample/src/main/kotlin/.../ChatInfoSharedMediaFragment.kt
Updated localFilter to check (imageUrl ?: thumbUrl) instead of imagePreviewUrl.
Formatting
stream-chat-android-ui-components/src/main/kotlin/.../FileAttachmentsView.kt
Minor whitespace/formatting adjustment between conditional branches (no logic changes).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Suggested labels

pr:breaking-change, pr:improvement

Suggested reviewers

  • gpunto

Poem

🐰 No more preview URLs so unclear,
Type-specific fields bring images near!
Thumbs and images, each in their place,
The deprecation puts things in space! ✨📸

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: deprecating imagePreviewUrl and using type-specific attachment URL fields instead.
Description check ✅ Passed The description covers the goal, implementation details, and testing approach. However, it omits UI change screenshots and the contributor/reviewer checklists required by the template.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bug/AND-1126_use_correct_image_urls

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
Copy Markdown

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/attachments/ChannelMediaAttachmentsActivity.kt`:
- Line 52: The localFilter predicate in ChannelMediaAttachmentsActivity.kt is
currently allowing attachments with only thumbUrl which breaks type-specific
loading; update the localFilter lambda (localFilter = { ... }) to be type-aware:
for attachments with type == "image" require a non-empty imageUrl, for video/gif
types permit thumbUrl or imageUrl as appropriate, and otherwise reject if the
required URL for that attachment.type is null/empty; ensure you reference the
attachment.type, attachment.imageUrl and attachment.thumbUrl fields in the
predicate so only eligible media reach the image-loading paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 20734022-96c2-428d-a3c5-db508e00a41e

📥 Commits

Reviewing files that changed from the base of the PR and between d7ce8ed and 2c14749.

📒 Files selected for processing (25)
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/attachments/ChannelMediaAttachmentsActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/chats/ChatsActivity.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/ImageAttachmentPreviewContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/LinkAttachmentContent.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/attachments/content/MediaAttachmentPreviewContent.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/preview/internal/MediaGalleryPage.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/channel/attachments/ChannelMediaAttachmentsScreen.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/util/extensions/internal/AttachmentExtensions.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/viewmodel/channel/ChannelMediaAttachmentsPreviewViewModel.kt
  • stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/utils/extensions/Attachment.kt
  • stream-chat-android-ui-common/src/test/kotlin/io/getstream/chat/android/ui/common/utils/extensions/AttachmentExtensionsTest.kt
  • stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/feature/chat/info/shared/media/ChatInfoSharedMediaFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryImagePageFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryPagerAdapter.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/internal/AttachmentGalleryVideoPageFragment.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/gallery/overview/internal/MediaAttachmentAdapter.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/MessageListView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/DefaultQuotedAttachmentView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/FileAttachmentsView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/GiphyMediaAttachmentView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/LinkAttachmentView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/view/internal/MediaAttachmentView.kt
  • stream-chat-android-ui-components/src/main/kotlin/io/getstream/chat/android/ui/feature/messages/list/adapter/viewholder/impl/GiphyViewHolder.kt

@sonarqubecloud
Copy link
Copy Markdown

@andremion andremion enabled auto-merge (squash) March 26, 2026 11:43
@andremion andremion merged commit 45c9f28 into develop Mar 26, 2026
15 checks passed
@andremion andremion deleted the bug/AND-1126_use_correct_image_urls branch March 26, 2026 11:50
@stream-public-bot stream-public-bot added the released Included in a release label Mar 26, 2026
@stream-public-bot
Copy link
Copy Markdown
Contributor

🚀 Available in v6.36.0

andremion added a commit that referenced this pull request Apr 7, 2026
* Improve `Message.createdLocallyAt` creation logic using estimated server time (#6199)

* Fix createdLocallyAt using NTP-style server clock offset estimation

Co-Authored-By: Claude <noreply@anthropic.com>

* Pr remarks

* Adjust thread message createdLocallyAt.

* Ensure exceedsSyncThreshold is compared against estimated server time (where applicable).

* Add max allowed offset.

---------

Co-authored-by: Claude <noreply@anthropic.com>

* [skip ci] Update SDK sizes

* Update README cover image (#6282)

* Fix XML image flicker caused by `interceptorCoroutineContext(Dispatchers.IO)` (#6284)

Co-authored-by: Claude <noreply@anthropic.com>

* [skip ci] Update SDK sizes

* AUTOMATION: Version Bump

* Fix race condition in plugin resolution during disconnect (#6269)

* Update `DependencyResolverTest` to verify error handling when dependency resolution races with disconnection.

* Prevent race conditions during disconnects in `ChatClient`.

* Handle unresolvable attachments in picker (#6285)

- Update `StorageHelper` and `AttachmentMetaDataMapper` to safely handle cases where content URIs (e.g. cloud-backed files) cannot be opened.
- Introduce `hasUnresolvedAttachments` state in `AttachmentsPickerViewModel` to track failed attachment resolutions.
- Show a toast message in both View-based and Compose attachment pickers when files are unavailable and need to be downloaded to the device.
- Add `clearUnresolvedAttachments` to reset the error state after it has been consumed by the UI.
- Add unit tests for unresolved attachment scenarios in `AttachmentsPickerViewModelTest`.

* [skip ci] Update SDK sizes

* Fix wrong message selected on quoted message long click (#6292)

* Use type-specific attachment URL fields and deprecate `imagePreviewUrl` (#6280)

* Deprecate imagePreviewUrl and use type-specific attachment URL fields

Co-Authored-By: Claude <noreply@anthropic.com>

* Extract common extensions.

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Expose optional completion callback for audio recording (#6290)

Co-authored-by: Claude <noreply@anthropic.com>

* AUTOMATION: Version Bump

* AUTOMATION: Clean Detekt Baseline Files (#6299)

Co-authored-by: adasiewiczr <17440581+adasiewiczr@users.noreply.github.com>

* Add support for intercepting CDN file requests (#6295)

* Add new CDN contract.

* Add CDN for document files.

* Add CDN support for downloading attachments.

* Deprecate current CDN methods.

* Add progress indicator snackbar.

* Add useDocumentGView config flag.

* Add file sharing cache handling.

* Add file sharing cache handling.

* Remove CDNResponse.kt

* Add tests

* PR remarks

* [skip ci] Update SDK sizes

* Post-merge clean-up.

* Post-merge clean-up.

* ApiDump.

* Improve attachment URI resolution and error handling in `AttachmentsPickerViewModel` and `AttachmentStorageHelper`.

- Add `isUriResolvable` to `StorageHelper` to verify if a content URI can be opened for reading.
- Implement `partitionResolvable` in `AttachmentStorageHelper` to separate metadata based on URI accessibility.
- Update `AttachmentsPickerViewModel.resolveAndSubmitUris` to exclude inaccessible URIs (e.g., undownloaded cloud files) from the submission.
- Ensure `hasUnresolvedAttachments` is correctly set when URIs are inaccessible, independent of file type support.
- Add unit tests in `AttachmentStorageHelperTest` and `AttachmentsPickerViewModelTest` to verify partitioning logic and view model state updates.

* Handle unresolvable attachments in XML

* apiDump.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: André Mion <andremion@gmail.com>
Co-authored-by: Gianmarco <47775302+gpunto@users.noreply.github.com>
Co-authored-by: stream-pr-merger[bot] <117762243+stream-pr-merger[bot]@users.noreply.github.com>
Co-authored-by: adasiewiczr <17440581+adasiewiczr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:bug Bug fix released Included in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants