Skip to content

Restyle unread divider and extract shared MessagesStripDivider#6417

Merged
andremion merged 1 commit into
developfrom
fix/sdk-unread-divider-restyle
May 6, 2026
Merged

Restyle unread divider and extract shared MessagesStripDivider#6417
andremion merged 1 commit into
developfrom
fix/sdk-unread-divider-restyle

Conversation

@andremion
Copy link
Copy Markdown
Contributor

@andremion andremion commented May 6, 2026

Goal

Address Issue #9 — Unread Messages divider design update from the SDK Testing Feedback Notion board: the unread separator inside the message list needs to follow the new Figma "MessagesDivider" strip design and surface the unread count inline.

The same Figma strip is used by the thread-replies "RepliesDivider", which the codebase already rendered with an identical inline layout. Pulling that layout into a shared internal primitive avoids the two screens drifting apart.

Implementation

  • Strip design. DefaultMessageUnreadSeparatorContent switches from the pill MessageDivider to the new full-width banner (background-subtle fill, top/bottom subtle borders, metadataEmphasis text).
  • Shared primitive. New internal MessagesStripDivider holds the shared layout; both unread and thread-replies separators delegate to it. The pre-existing inline strip code in DefaultMessageThreadSeparatorContent is removed.
  • Naming aligned with Figma. MessageDividerMessagesDateDivider. Visual unchanged.
  • Snapshot coverage. Per-component MessagesDateDividerTest and MessagesStripDividerTest, plus list-level unread separator visible and thread separator cases. The thread separator previously had zero snapshot coverage.

Important

Decision — count via %d in the existing string key

stream_compose_message_list_unread_separator is updated from "Unread Messages" to "%d unread messages" and all 7 localised resources mirror the same %d pattern.

Considered a <plurals> resource (consistent with how the thread-replies separator is structured) but rejected: changing the resource type would silently break customers who already override the string. With the current change:

  • Customers with a custom string that omits %d get their original copy back, count silently dropped — same observable behaviour as before this PR.
  • Customers with a custom string that includes %d get the count interpolated.

No public API or resource-type change. Existing overrides stay valid.

🎨 UI Changes

Before After
img img
Screenshot_20260506_093653 Screenshot_20260506_093612

Testing

  1. Build and run the Compose sample app on this branch.
  2. Open a channel that has unread messages.
    • Expected: a full-width strip sits at the read/unread boundary, reading e.g. "9 unread messages" (count matches the channel's unread count). The strip has subtle 1.dp top/bottom borders and a very subtle warm-gray fill.
    • Expected: the strip scrolls with the surrounding messages (it is not floating).
  3. Read past the last unread message (or open another channel and come back).
    • Expected: the strip is removed automatically; no manual dismiss affordance.
  4. Open a thread that has multiple replies.
    • Expected: the "X replies" banner between the parent message and the replies uses the same strip styling as the unread banner (same fill, borders, typography).
  5. Switch to a non-English locale (e.g. Spanish, Japanese, Korean) and reopen the channel with unread messages.
    • Expected: the banner copy reads in the locale, with the count correctly substituted in (e.g. "9 mensajes no leídos", "9件の未読メッセージ", "9개의 읽지 않은 메시지").
  6. Open the channel with date separators (cross-day messages).
    • Expected: the date pill is unchanged — same shape, same subtle background, same typography. Only the unread/replies banners changed.

Summary by CodeRabbit

  • New Features
    • Message lists now display date separators to better organize conversations chronologically.
    • Unread and thread reply indicators now show dynamic counts in all supported languages (e.g., "5 unread messages," "3 replies").

@andremion andremion added the pr:improvement Improvement label May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

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

🎉 Great job! This PR is ready for review.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 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.37 MB 12.38 MB 0.00 MB 🟢

@andremion
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 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
Copy Markdown

coderabbitai Bot commented May 6, 2026

Walkthrough

This PR refactors message list separators by introducing two new reusable UI components—MessagesDateDivider and MessagesStripDivider—that replace static separators with themed, dynamically-content composables. Updates localize unread message counts across nine language files with %d placeholders for dynamic count rendering.

Changes

Message List Separator Refactoring

Layer / File(s) Summary
UI Component Definitions
src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessagesDateDivider.kt, MessagesStripDivider.kt
Two new internal composables introduced: MessagesDateDivider() (renamed from MessageDivider) for date separators, and MessagesStripDivider() for unread/thread separators with dynamic text and theme-aware styling. Helpers added for "Today", "Absolute Date", "Unread", and "Replies" variants.
Integration & Usage
src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt
Date, unread, and thread separators in DefaultMessage*SeparatorContent blocks replaced to use new MessagesDateDivider and MessagesStripDivider components. Border utilities removed; localized count strings wired via stringResource and pluralStringResource.
Localization
src/main/res/values*/strings.xml (9 files)
stream_compose_message_list_unread_separator updated in values, values-es, values-fr, values-hi, values-in, values-it, values-ja, values-ko to support %d placeholder for dynamic unread count formatting.
API / Compilation
api/stream-chat-android-compose.api
New singleton holder classes ComposableSingletons$MessageItemKt and ComposableSingletons$MessagesDateDividerKt added to API surface (auto-generated by Compose compiler).
Tests
src/test/kotlin/io/getstream/chat/android/compose/ui/messages/list/MessagesDateDividerTest.kt, MessagesStripDividerTest.kt, MessageListTest.kt
New Paparazzi snapshot tests for date and strip dividers; updated MessageListTest with two new scenarios for unread and thread separators, plus test state helpers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes


🐰 New dividers hop into the list,
With counts that dance, no more they're missed,
Fresh Compose components, gleaming bright,
Localized for each language's sight!
Test snapshots guard the UI light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% 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 summarizes the main changes: restyling the unread divider and extracting a shared MessagesStripDivider component, which aligns with the PR's primary objectives.
Description check ✅ Passed The PR description is comprehensive and follows the template structure with Goal, Implementation, UI Changes, Testing, and includes detailed decision rationale. Some optional sections (Contributor/Reviewer Checklist, GIF) are not checked.
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/sdk-unread-divider-restyle

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@stream-chat-android-compose/src/main/res/values-it/strings.xml`:
- Around line 192-193: Reorder the two Italian string entries so they match the
canonical alphabetical ordering used in other locales: move the element with
name="stream_compose_message_list_unread_separator" to appear before the element
with name="stream_compose_message_list_unsupported_attachment"; update the XML
so the two keys are in the same order as in
values-fr/values-es/values-in/values-ja/values-ko and values-hi to satisfy
Spotless ordering rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 73431f0a-c380-411e-8bd8-8212933d595c

📥 Commits

Reviewing files that changed from the base of the PR and between db25173 and 899259e.

⛔ Files ignored due to path filters (6)
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.list_MessagesDateDividerTest_messages_date_divider_absolute_date.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.list_MessagesDateDividerTest_messages_date_divider_today.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.list_MessagesStripDividerTest_messages_strip_divider_replies.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages.list_MessagesStripDividerTest_messages_strip_divider_unread.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages_MessageListTest_thread_separator.png is excluded by !**/*.png
  • stream-chat-android-compose/src/test/snapshots/images/io.getstream.chat.android.compose.ui.messages_MessageListTest_unread_separator_visible.png is excluded by !**/*.png
📒 Files selected for processing (15)
  • stream-chat-android-compose/api/stream-chat-android-compose.api
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessageItem.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessagesDateDivider.kt
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/messages/list/MessagesStripDivider.kt
  • stream-chat-android-compose/src/main/res/values-es/strings.xml
  • stream-chat-android-compose/src/main/res/values-fr/strings.xml
  • stream-chat-android-compose/src/main/res/values-hi/strings.xml
  • stream-chat-android-compose/src/main/res/values-in/strings.xml
  • stream-chat-android-compose/src/main/res/values-it/strings.xml
  • stream-chat-android-compose/src/main/res/values-ja/strings.xml
  • stream-chat-android-compose/src/main/res/values-ko/strings.xml
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/messages/MessageListTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/messages/list/MessagesDateDividerTest.kt
  • stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/messages/list/MessagesStripDividerTest.kt

Comment thread stream-chat-android-compose/src/main/res/values-it/strings.xml Outdated
Adopt the new strip design for the unread separator: full-width banner with
backgroundCoreSurfaceSubtle fill, top/bottom borderCoreSubtle, metadataEmphasis
text, and an inline %d count.

Pull the shared strip layout into MessagesStripDivider, used by both the unread
and the thread-replies separators. Rename the existing MessageDivider (pill) to
MessagesDateDivider so the codebase tracks the Figma vocabulary. Normalize the
thread separator's testTag to mergeDescendants semantics, matching the unread
and date wrappers.

Add Paparazzi coverage: per-component MessagesDateDividerTest and
MessagesStripDividerTest, plus list-level cases for the unread separator on
screen and a thread-mode separator (previously zero coverage).
@andremion andremion force-pushed the fix/sdk-unread-divider-restyle branch from 899259e to f24c5f7 Compare May 6, 2026 09:00
@andremion andremion marked this pull request as ready for review May 6, 2026 09:03
@andremion andremion requested a review from a team as a code owner May 6, 2026 09:03
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 6, 2026

@andremion andremion merged commit 75cafde into develop May 6, 2026
16 checks passed
@andremion andremion deleted the fix/sdk-unread-divider-restyle branch May 6, 2026 09:40
@stream-public-bot stream-public-bot added the released Included in a release label May 22, 2026
@stream-public-bot
Copy link
Copy Markdown
Contributor

🚀 Available in v7.2.0

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

Labels

pr:improvement Improvement released Included in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants