Skip to content

Let integrators supply channel header click labels for TalkBack#6447

Merged
andremion merged 6 commits into
developfrom
fix/compose-channel-header-avatar-a11y
May 20, 2026
Merged

Let integrators supply channel header click labels for TalkBack#6447
andremion merged 6 commits into
developfrom
fix/compose-channel-header-avatar-a11y

Conversation

@andremion
Copy link
Copy Markdown
Contributor

@andremion andremion commented May 19, 2026

Goal

Give TalkBack a concrete verb when the user focuses the channel header trailing avatar or the title section, instead of the generic "double-tap to activate" hint. Because the click actions are integrator-defined, the SDK exposes the labels as paired parameters and ships no default label of its own — the action's owner also owns the label.

Implementation

SDK plumbing. Every layer that already exposes onChannelAvatarClick / onHeaderTitleClick now exposes a paired onChannelAvatarClickLabel / onHeaderTitleClickLabel: String? = null:

  • ChannelScreen (public): new defaulted params, threaded into DefaultTopBarContent.
  • ChannelHeaderParams (factory): new defaulted fields onHeaderTitleClickLabel, onChannelAvatarClickLabel.
  • ChannelHeader (public): new defaulted params, threaded into the trailing- and center-content params.
  • ChannelHeaderCenterContentParams.onClickLabel, ChannelHeaderTrailingContentParams.onClickLabel: new defaulted fields (additive — non-breaking for Compose data-class consumers).
  • DefaultChannelHeaderTrailingContent and DefaultChannelHeaderCenterContent: pass the supplied label straight to Modifier.clickable(onClickLabel = …, role = Role.Button). When the integrator doesn't supply one, null flows through and TalkBack falls back to its generic verb hint.

No SDK default label. The SDK doesn't know what the integrator's callback actually does (open settings? show a sheet? something else?), so it must not hard-code a label like "Open conversation info". The integrator owns both the action and its announced verb.

Sample app demonstrates the integrator side. ChannelActivity (the renamed sample messages screen) passes onChannelAvatarClickLabel = stringResource(R.string.messages_open_channel_info) alongside ::openChannelInfo, with the label defined in the sample's own strings.xml.

Sample refactor. While in this file, MessagesActivity is renamed to ChannelActivity and moved to the sample/ui/channel package (alongside DirectChannelInfoActivity and GroupChannelInfoActivity). All callers (AndroidManifest, ChannelsActivity, StartupActivity, channel info / drafts / reminders / add-channel activities) are updated.

Public API: additive trailing-defaulted params on ChannelScreen, ChannelHeader, ChannelHeaderParams, ChannelHeaderCenterContentParams, ChannelHeaderTrailingContentParams. API dump regenerated.

Note: the scanner also flagged the avatar's 40 dp touch-target height. Deliberately not addressed here — any layout-level expansion either resizes the avatar (visual change) or shifts the centered title text. To be revisited separately.

Testing

Enable TalkBack on a physical device, run the sample.

  1. Open a 1:1 or group channel.
  2. Focus the trailing avatar in the header. Expected: TalkBack announces "<avatar contents>, button. Double-tap to open channel info" — the verb comes from the sample's messages_open_channel_info string, demonstrating the integrator-supplied label.
  3. Focus the channel title section. Expected: no click verb is announced because MessagesActivity/ChannelActivity doesn't wire onHeaderTitleClick in the sample (the SDK doesn't make assumptions on its behalf). TalkBack reads only the title text. If a future sample integration wires onHeaderTitleClick, the matching onHeaderTitleClickLabel is exposed and ready to use.
  4. (For SDK consumers: pass a custom onChannelAvatarClick = { doSomethingElse() } without onChannelAvatarClickLabel. Confirm TalkBack falls back to the generic "double-tap to activate" hint — the SDK doesn't announce a misleading default.)

Summary by CodeRabbit

  • New Features

    • Enhanced accessibility support with semantic labels for header title and channel avatar click actions.
  • Refactor

    • Restructured navigation flow to use unified channel activity for improved app navigation consistency.

Review Change Stack

@andremion andremion added the pr:improvement Improvement label May 19, 2026
@andremion
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 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 (or ignored for dependabot PRs).

🎉 Great job! This PR is ready for review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dc261648-eb15-4f6c-aa8e-a969a11abc07

📥 Commits

Reviewing files that changed from the base of the PR and between b32775f and 0099600.

📒 Files selected for processing (16)
  • stream-chat-android-compose-sample/src/demo/java/io/getstream/chat/android/compose/sample/ui/StartupActivity.kt
  • stream-chat-android-compose-sample/src/main/AndroidManifest.xml
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/add/AddChannelActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/add/group/AddGroupChannelActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/draft/DraftChannelActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/list/ChannelsActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/reminders/MessageRemindersActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/ChannelActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/GroupChannelInfoActivity.kt
  • stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/pinned/PinnedMessagesActivity.kt
  • stream-chat-android-compose-sample/src/main/res/values/strings.xml
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/ChannelScreen.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/header/ChannelHeader.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/ChatComponentFactoryParams.kt

Walkthrough

This PR adds semantic accessibility labels to channel header interactive elements and refactors the sample app's main activity. ChannelHeader and ChannelScreen now accept optional onHeaderTitleClickLabel and onChannelAvatarClickLabel string parameters, threaded through the theme factory to enable accessible click descriptions. MessagesActivity is renamed to ChannelActivity, moved to a ui.channel package, and all sample app navigation endpoints are updated to reference the new class and package location.

Changes

Channel Header Accessibility Enhancements

Layer / File(s) Summary
Header composable accessibility parameters
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/header/ChannelHeader.kt
ChannelHeader accepts onHeaderTitleClickLabel and onChannelAvatarClickLabel, wires them into center and trailing content, and applies Role.Button with label to title and avatar clickable modifiers.
ChannelScreen label threading
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/ChannelScreen.kt
ChannelScreen function accepts and documents two new optional label parameters, forwards them through DefaultTopBarContent, and populates ChannelHeaderParams for propagation to the header.
Theme factory parameter classes
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactoryParams.kt
ChannelHeaderParams, ChannelHeaderCenterContentParams, and ChannelHeaderTrailingContentParams data classes extended with nullable label string fields and corresponding KDoc entries.
Component factory wiring
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/theme/ChatComponentFactory.kt
ChannelHeader, ChannelHeaderCenterContent, and ChannelHeaderTrailingContent default implementations forward onClickLabel values from params to their underlying composables.
Public API surface
stream-chat-android-compose/api/stream-chat-android-compose.api
Generated API surface updated to reflect expanded ChannelScreen, ChannelHeader, and parameter class signatures with new String label fields and getter methods.
Sample app accessibility wiring
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/ChannelActivity.kt, src/main/res/values/strings.xml
ChannelActivity provides onChannelAvatarClickLabel from localized messages_open_channel_info string resource.

Sample App Activity Refactoring

Layer / File(s) Summary
Activity rename and relocation
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/ui/channel/ChannelActivity.kt
MessagesActivity renamed to ChannelActivity and moved to io.getstream.chat.android.compose.sample.ui.channel package; imports adjusted and createIntent factory retargeted.
Manifest and startup routing
stream-chat-android-compose-sample/src/main/AndroidManifest.xml, src/demo/java/io/getstream/chat/android/compose/sample/ui/StartupActivity.kt
AndroidManifest reference changed to .ui.channel.ChannelActivity, and StartupActivity push-notification routing updated to navigate to ChannelActivity.
Navigation across sample activities
stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/channel/add/AddChannelActivity.kt, feature/channel/add/group/AddGroupChannelActivity.kt, feature/channel/draft/DraftChannelActivity.kt, feature/channel/list/ChannelsActivity.kt, feature/reminders/MessageRemindersActivity.kt, ui/channel/GroupChannelInfoActivity.kt, ui/pinned/PinnedMessagesActivity.kt
All activities that navigate to the messages/channel screen import and use ChannelActivity instead of MessagesActivity for intent creation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • gpunto
  • VelikovPetar

🐰 A rabbit hops through the compose tree,
Labels whisper semantics wild and free,
ChannelActivity claims its rightful place,
Accessibility shines on every face!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main purpose: enabling integrators to supply click labels for TalkBack accessibility in the channel header.
Description check ✅ Passed The description provides comprehensive coverage of Goal, Implementation, and Testing sections with detailed explanations. UI Changes section is not applicable since this is an accessibility improvement without visual UI changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 fix/compose-channel-header-avatar-a11y

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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.82 MB 5.82 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.02 MB 11.02 MB 0.00 MB 🟢
stream-chat-android-compose 12.40 MB 12.41 MB 0.00 MB 🟢

@andremion andremion marked this pull request as ready for review May 19, 2026 15:29
@andremion andremion requested a review from a team as a code owner May 19, 2026 15:29
@andremion andremion marked this pull request as draft May 20, 2026 08:36
@andremion andremion changed the title Label channel header avatar click action for TalkBack Let integrators supply channel header click labels for TalkBack May 20, 2026
@andremion andremion marked this pull request as ready for review May 20, 2026 09:03
@andremion andremion enabled auto-merge (squash) May 20, 2026 09:03
@andremion
Copy link
Copy Markdown
Contributor Author

@CodeRabbit full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Full review triggered.

@andremion andremion force-pushed the fix/compose-channel-header-avatar-a11y branch from 0099600 to bee3a49 Compare May 20, 2026 09:11
@andremion andremion force-pushed the fix/compose-channel-header-avatar-a11y branch from bee3a49 to c8c8b78 Compare May 20, 2026 09:42
andremion added 2 commits May 20, 2026 13:57
Extract each preview body into an internal helper so the
ChannelHeaderTest can drive snapshots from the same composables
that back the @Preview annotations, mirroring the pattern used
in ChannelMediaAttachmentsScreen.

Moves the test next to its source under
ui.messages.header, adds a thread-mode preview, and adds a
few-members preview to keep member-count coverage that the old
test had with channelWithFewMembers.

Drops the user-typing preview/test: typing is rendered as a
MessageListTypingIndicatorItemContent in the message list since
PR #6206, so the header's typingUsers parameter no longer
produces a visible change.
@sonarqubecloud
Copy link
Copy Markdown

@andremion andremion merged commit f868ec6 into develop May 20, 2026
16 checks passed
@andremion andremion deleted the fix/compose-channel-header-avatar-a11y branch May 20, 2026 14:01
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.

2 participants