Skip to content

Update file picker UI and refactor radio controls #6216

Open
andremion wants to merge 5 commits intoredesign/update-stream-design-tokensfrom
redesign/files-picker-ui-update
Open

Update file picker UI and refactor radio controls #6216
andremion wants to merge 5 commits intoredesign/update-stream-design-tokensfrom
redesign/files-picker-ui-update

Conversation

@andremion
Copy link
Contributor

@andremion andremion commented Mar 6, 2026

Goal

Apply the updated Stream Design System tokens to the radio/check controls and redesign the file picker UI to align with the new design spec.

Implementation

  • StreamDesign.Colors — updated colors from Figma
  • RadioControls.kt (previously RadioCheck.kt) — introduced a RadioButton component (filled dot indicator), extracted a private RadioControlBase composable that owns the shared container logic (sizing, shape,
    4-state modifier, click handling), and merged both RadioButton and RadioCheck into a single file.
  • FilesPicker / AttachmentFilePicker — the trailing icon is replaced with a chevron; RadioButton is used for
    single-selection mode and RadioCheck for multi-selection mode; StreamHorizontalDivider separates items.
  • StreamHorizontalDivider — default thickness updated from 0.5dp to 1dp.
  • Replaced stream_compose_ic_more_files drawable with stream_compose_ic_chevron_right.

🎨 UI Changes

Please check the snapshot files

Testing

  1. Open the message composer and tap the file attachment button.
  2. Verify the file picker UI.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added RadioButton component for single-selection controls in file pickers.
  • UI Improvements

    • Files picker header is now clickable for easier interaction.
    • Increased divider thickness for better visual definition.
    • Enhanced file selection lists with improved spacing and icon styling.
    • Added chevron-right icons for better visual hierarchy.
  • Theme Updates

    • Added new color token for radio button indicators.

@andremion andremion added the pr:improvement Improvement label Mar 6, 2026
@andremion andremion requested a review from a team as a code owner March 6, 2026 11:54
@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 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.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 6, 2026

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Walkthrough

This PR introduces a new RadioButton composable, refactors file and attachment picker UI components with clickable headers and chevron icons, updates radio control color tokens, and modifies the public API surface of ComposableSingletons classes by renaming and adding lambda field accessors.

Changes

Cohort / File(s) Summary
Public API Surface
stream-chat-android-compose/api/stream-chat-android-compose.api
Breaking changes: renamed ComposableSingletons$RadioCheckKt to ComposableSingletons$RadioControlsKt, added lambda-2/3/4 fields and corresponding accessors across multiple singletons, updated StreamDesign$Colors constructors and copy method signatures, added getControlRadioButtonIndicator accessor.
Radio Controls
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/common/RadioControls.kt
Added new internal RadioButton composable, refactored RadioCheck to use new RadioControlBase helper with content slot, updated event handling to use onChange naming.
File/Attachment Pickers
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt, stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt
Replaced static headers with clickable rows including chevron-right icons, updated spacing and alignment, added StreamHorizontalDividers, introduced conditional RadioCheck/RadioButton rendering based on allowMultipleSelection, extracted reusable metadata constants.
Theme & Colors
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamDesign.kt
Restructured color tokens: removed parameter-based initialization for controlRadioCheckBgSelected/IconSelected, added default values inline, introduced new controlRadioButtonIndicator token with textOnAccent default.
Minor UI Updates
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/StreamHorizontalDivider.kt
Updated default thickness parameter from 0.5.dp to 1.dp.
Drawable Resources
stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_chevron_right.xml, stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_files.xml
Added new chevron-right icon vector drawable (20x20dp), removed stream_compose_ic_more_files.xml.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

pr:breaking-change

Suggested reviewers

  • gpunto
  • VelikovPetar

Poem

🐰 A RadioButton hops in place,
With chevrons guiding through the space,
Pickers now clickable and divine,
Colors aligned with each fine line,
Radio controls refined to shine! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 clearly summarizes the main changes: updating the file picker UI and refactoring radio controls, which align with the primary objectives of the changeset.
Description check ✅ Passed The description covers the required sections including Goal, Implementation with specific technical details, UI Changes reference, and Testing instructions. All major components are addressed.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch redesign/files-picker-ui-update

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

Caution

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

⚠️ Outside diff range comments (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt (1)

127-167: ⚠️ Potential issue | 🟠 Major

Expose selection semantics on the file row.

This row is the actual click target, but it doesn't expose the selection state or control type to assistive technologies. The trailing RadioCheck/RadioButton have onCheckedChange = null, making them non-interactive displays. Use .selectable() with the appropriate Role to provide semantic information about whether the item is selected and whether it behaves as a checkbox or radio button.

♿ Suggested fix
+import androidx.compose.foundation.selection.selectable
+import androidx.compose.ui.semantics.Role
+
     Row(
         Modifier
             .fillMaxWidth()
-            .clickable { onItemSelected(fileItem) }
+            .selectable(
+                selected = fileItem.isSelected,
+                role = if (allowMultipleSelection) Role.Checkbox else Role.RadioButton,
+                onClick = { onItemSelected(fileItem) },
+            )
             .padding(StreamTokens.spacingSm),
         verticalAlignment = Alignment.CenterVertically,
         horizontalArrangement = Arrangement.spacedBy(StreamTokens.spacingSm),
     ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt`
around lines 127 - 167, The row currently uses .clickable and leaves the radio
controls non-interactive; replace the Row's .clickable with
Modifier.selectable(selected = fileItem.isSelected, onClick = {
onItemSelected(fileItem) }, role = if (allowMultipleSelection) Role.Checkbox
else Role.Radio) so accessibility exposes selection state and control type; keep
the trailing RadioCheck/RadioButton as visual indicators but leave their
onCheckedChange = null (read-only) since the selectable on the Row handles
interaction.
🤖 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/api/stream-chat-android-compose.api`:
- Around line 3594-3595: Add a changelog entry under the UNRELEASED section's
"⚠️ Changed" for stream-chat-android-compose documenting that the
StreamDesign.Colors ABI changed due to the new controlRadioButtonIndicator token
(the public constructor/copy signature for StreamDesign.Colors was modified),
and note that apps that instantiate or copy StreamDesign.Colors directly will
need recompilation and may require updates to custom theme code; repeat the same
note for the related ABI changes you observed (the other StreamDesign.Colors
constructor/copy signature changes referenced at the other locations).

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt`:
- Around line 98-101: The chevron Icon in FilesPicker (the Icon call using
painterResource(id = R.drawable.stream_compose_ic_chevron_right)) is decorative
but currently has a non-null contentDescription; change its contentDescription
to null so the chevron is ignored by accessibility services (i.e., update the
Icon in FilesPicker.kt to use contentDescription = null).

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt`:
- Around line 219-223: Change the Icon in AttachmentFilePicker's chevron to use
contentDescription = null (replace the current contentDescription =
stringResource(id = contentDescriptionId)), then remove the now-unused
contentDescriptionId parameter from the RequestAdditionalAccessButton
declaration and its usages (all callers currently pass the same textId) and
update callers to stop supplying that argument; ensure
RequestAdditionalAccessButton and any downstream references compile after
removing the parameter.

---

Outside diff comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt`:
- Around line 127-167: The row currently uses .clickable and leaves the radio
controls non-interactive; replace the Row's .clickable with
Modifier.selectable(selected = fileItem.isSelected, onClick = {
onItemSelected(fileItem) }, role = if (allowMultipleSelection) Role.Checkbox
else Role.Radio) so accessibility exposes selection state and control type; keep
the trailing RadioCheck/RadioButton as visual indicators but leave their
onCheckedChange = null (read-only) since the selectable on the Row handles
interaction.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9067aa7a-a5be-45fa-84c1-4644dc704c82

📥 Commits

Reviewing files that changed from the base of the PR and between 2a28913 and 79158b9.

⛔ Files ignored due to path filters (37)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.preview_MediaGalleryPreviewOptionsMenuTest_media_gallery_options_menu_for_other_user.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.preview_MediaGalleryPreviewOptionsMenuTest_media_gallery_options_menu_for_own_user.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.attachments.preview_MediaGalleryPreviewScreenTest_media_gallery_screen_with_options_menu.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.attachments_ChannelFilesAttachmentsContentTest_content.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.attachments_ChannelFilesAttachmentsContentTest_content_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.attachments_ChannelFilesAttachmentsContentTest_loading_more.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.attachments_ChannelFilesAttachmentsContentTest_loading_more_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.attachments_ChannelMediaAttachmentsContentTest_loading_more_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_ChannelInfoMemberInfoModalSheetTest_banned_member.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_ChannelInfoMemberInfoModalSheetTest_banned_member_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_ChannelInfoMemberInfoModalSheetTest_not_banned_member.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_ChannelInfoMemberInfoModalSheetTest_not_banned_member_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_DirectChannelInfoContentTest_content.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_DirectChannelInfoContentTest_content_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_DirectChannelInfoContentTest_loading_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_GroupChannelInfoContentTest_collapsed_members.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_GroupChannelInfoContentTest_collapsed_members_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_GroupChannelInfoContentTest_expanded_members.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_GroupChannelInfoContentTest_expanded_members_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channel.info_GroupChannelInfoContentTest_loading_in_dark_mode.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelListTest_loaded_channels.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelListTest_loading_more_channels.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelListTest_search_results.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.channels_ChannelsTest_loaded_channels.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.attachments.files_FilesPickerTest_multiple_selection.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.components.attachments.files_FilesPickerTest_single_selection.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments_AttachmentFilePickerTest_multiple_selection.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.attachments_AttachmentFilePickerTest_single_selection.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.pinned_PinnedMessageListTest_loaded_pinned_messages.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.pinned_PinnedMessageListTest_loading_more_pinned_messages.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadItemTest_threadItem.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loaded_threads_with_unread_banner.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_ThreadListTest_loading_more_threads.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_UnreadThreadsBannerTest_multiple_unread_threads.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_UnreadThreadsBannerTest_no_unread_threads.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.threads_UnreadThreadsBannerTest_one_unread_thread.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/StreamHorizontalDivider.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/common/RadioControls.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/StreamDesign.kt
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_chevron_right.xml
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_files.xml
💤 Files with no reviewable changes (1)
  • stream-chat-android-compose/src/main/res/drawable/stream_compose_ic_more_files.xml

Comment on lines +3594 to +3595
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for migration and changelog files
docs="$(fd -t f -i -E 'node_modules' -E '.git' 'migration|changelog' . || true)"

if [ -z "$docs" ]; then
  echo "No migration or changelog files found in initial search."
  # Try broader search
  docs="$(find . -maxdepth 3 -type f \( -iname '*migration*' -o -iname '*changelog*' -o -iname 'CHANGES*' \) 2>/dev/null || true)"
fi

if [ -z "$docs" ]; then
  echo "No migration or changelog files found after broad search."
  exit 1
fi

echo "=== Files found ==="
echo "$docs"
echo ""
echo "=== Searching for relevant content ==="
echo "$docs" | xargs -r grep -l -i 'StreamDesign\|controlRadioButton\|RadioControls\|RadioCheck\|v7\|migration\|breaking' 2>/dev/null | head -20

Repository: GetStream/stream-chat-android

Length of output: 183


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, get the size of CHANGELOG.md to decide how to read it
wc -l ./CHANGELOG.md

echo ""
echo "=== Searching for StreamDesign or controlRadioButton mentions ==="
rg -n -i 'StreamDesign|controlRadioButton|theme.*Colors|Colors.*constructor|breaking.*change|migration' ./CHANGELOG.md | head -50

Repository: GetStream/stream-chat-android

Length of output: 12774


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for v7 or recent theme changes in CHANGELOG ==="
rg -n -i '^#+\s+(v7|7\.|theme|color|radio)' ./CHANGELOG.md | head -20

echo ""
echo "=== Searching for StreamDesign or design tokens ==="
rg -n -i 'streamdesign|design.*token|theme.*color|colors.*constructor' ./CHANGELOG.md | head -20

echo ""
echo "=== Looking at the very top of CHANGELOG to see current version context ==="
head -50 ./CHANGELOG.md

Repository: GetStream/stream-chat-android

Length of output: 134


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Top of CHANGELOG.md ==="
head -100 ./CHANGELOG.md

echo ""
echo "=== Any mention of radio, indicator, or control ==="
rg -n -i 'radio|indicator|control.*button|button.*control' ./CHANGELOG.md | head -20

Repository: GetStream/stream-chat-android

Length of output: 4908


Add changelog entry documenting the StreamDesign.Colors ABI change.

The new controlRadioButtonIndicator token changes the public StreamDesign.Colors constructor/copy ABI. This breaking change is not documented in the CHANGELOG. Add an entry to the "⚠️ Changed" section under stream-chat-android-compose in the UNRELEASED section, documenting that StreamDesign.Colors constructor signature has changed and apps that instantiate or copy this type directly will need recompilation and may require custom theme code updates.

Same applies to related changes at lines 3670-3671 and 3791-3791.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@stream-chat-android-compose/api/stream-chat-android-compose.api` around lines
3594 - 3595, Add a changelog entry under the UNRELEASED section's "⚠️ Changed"
for stream-chat-android-compose documenting that the StreamDesign.Colors ABI
changed due to the new controlRadioButtonIndicator token (the public
constructor/copy signature for StreamDesign.Colors was modified), and note that
apps that instantiate or copy StreamDesign.Colors directly will need
recompilation and may require updates to custom theme code; repeat the same note
for the related ABI changes you observed (the other StreamDesign.Colors
constructor/copy signature changes referenced at the other locations).

Comment on lines +98 to +101
Icon(
painter = painterResource(id = R.drawable.stream_compose_ic_chevron_right),
contentDescription = stringResource(id = R.string.stream_compose_send_attachment),
tint = ChatTheme.colors.textSecondary,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Read the FilesPicker.kt file around lines 98-101
cat -n stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt | sed -n '90,110p'

Repository: GetStream/stream-chat-android

Length of output: 1013


🏁 Script executed:

# Check the broader context of this Icon - what is the parent composable and what does it do?
cat -n stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt | sed -n '75,110p'

Repository: GetStream/stream-chat-android

Length of output: 1534


🏁 Script executed:

# Check what the string resource "stream_compose_send_attachment" actually says
rg -t kotlin "stream_compose_send_attachment" stream-chat-android-compose/src/main/res/values/ | head -5

Repository: GetStream/stream-chat-android

Length of output: 55


🏁 Script executed:

# Search for the string resource definition in all string files
rg "stream_compose_send_attachment" stream-chat-android-compose/src/main/res/

Repository: GetStream/stream-chat-android

Length of output: 489


Set the chevron's contentDescription to null to mark it as decorative.

The Icon uses contentDescription = stringResource(id = R.string.stream_compose_send_attachment) ("Send attachment"), which is unrelated to the chevron's visual role. Since the parent Row's text already describes the action ("Recent files") and the icon is non-interactive decoration, keeping a non-null contentDescription will cause TalkBack to announce a misleading extra label. Use contentDescription = null instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/attachments/files/FilesPicker.kt`
around lines 98 - 101, The chevron Icon in FilesPicker (the Icon call using
painterResource(id = R.drawable.stream_compose_ic_chevron_right)) is decorative
but currently has a non-null contentDescription; change its contentDescription
to null so the chevron is ignored by accessibility services (i.e., update the
Icon in FilesPicker.kt to use contentDescription = null).

Comment on lines +219 to +223
Icon(
painter = painterResource(id = R.drawable.stream_compose_ic_chevron_right),
contentDescription = stringResource(id = contentDescriptionId),
tint = ChatTheme.colors.textSecondary,
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the AttachmentFilePicker.kt file
find . -name "AttachmentFilePicker.kt" -type f

Repository: GetStream/stream-chat-android

Length of output: 198


🏁 Script executed:

# Read the file to understand the context around lines 219-223
cat -n stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt | head -250 | tail -80

Repository: GetStream/stream-chat-android

Length of output: 3323


🏁 Script executed:

# Let's also check the RequestAdditionalAccessButton function definition
rg -A 30 "fun RequestAdditionalAccessButton" stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt

Repository: GetStream/stream-chat-android

Length of output: 1086


Set the chevron Icon contentDescription to null.

The visible row text already announces the action, so the Icon repeating the same contentDescription creates a duplicate spoken announcement. Change line 221 to contentDescription = null, then remove the contentDescriptionId parameter from RequestAdditionalAccessButton since it's unused after this change (all callers pass the same value as textId anyway).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/attachments/AttachmentFilePicker.kt`
around lines 219 - 223, Change the Icon in AttachmentFilePicker's chevron to use
contentDescription = null (replace the current contentDescription =
stringResource(id = contentDescriptionId)), then remove the now-unused
contentDescriptionId parameter from the RequestAdditionalAccessButton
declaration and its usages (all callers currently pass the same textId) and
update callers to stop supplying that argument; ensure
RequestAdditionalAccessButton and any downstream references compile after
removing the parameter.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.69 MB 0.44 MB 🟡
stream-chat-android-ui-components 10.60 MB 11.00 MB 0.40 MB 🟡
stream-chat-android-compose 12.81 MB 12.03 MB -0.78 MB 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:improvement Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant