-
Notifications
You must be signed in to change notification settings - Fork 372
feat(ui): Add MessagePreviewFormatter for customization
#2441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit introduces a new `MessagePreviewFormatter` class to allow developers to customize how message previews are formatted in the channel list. Previously, the formatting logic was hardcoded within the `StreamMessagePreviewText` and `StreamDraftMessagePreviewText` widgets. This change extracts that logic into a new, configurable `StreamMessagePreviewFormatter` class. Key changes: - **`MessagePreviewFormatter`:** A new abstract class is introduced to define the contract for formatting message and draft message previews. - **`StreamMessagePreviewFormatter`:** The default implementation that replicates the previous hardcoded behavior. It can be extended to override specific formatting methods (e.g., for polls, attachments, or group messages). - **`StreamChatConfiguration`:** The configuration now accepts an optional `messagePreviewFormatter` instance, allowing for app-wide customization. - The `StreamMessagePreviewText` and `StreamDraftMessagePreviewText` widgets have been refactored to use the new formatter, significantly simplifying their implementation.
|
Warning Rate limit exceeded@xsahil03x has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 47 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (3)
WalkthroughThis PR introduces a centralized message preview formatting system for the Stream Chat Flutter package. It adds a new Changes
Sequence Diagram(s)sequenceDiagram
participant Widget as Message Preview Widget
participant Config as StreamChatConfiguration
participant Formatter as StreamMessagePreviewFormatter
participant Theme as Theme/Translations
Widget->>Config: access config.messagePreviewFormatter
Config-->>Widget: returns MessagePreviewFormatter
Widget->>Formatter: formatMessage(context, message, ...)
Formatter->>Formatter: determine message type<br/>(deleted/system/poll/regular)
Formatter->>Formatter: extract message content<br/>(attachments, text, etc.)
Formatter->>Formatter: apply sender context<br/>(current user/DM/group)
Formatter->>Theme: resolve theme colors & translations
Formatter->>Formatter: build TextSpan with styling<br/>(bold mentions, colors)
Formatter-->>Widget: return formatted TextSpan
Widget->>Widget: render Text.rich(textSpan)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart (1)
481-517: Ensure draft prefix styling is applied even when textStyle is nullIn
formatDraftMessage, the bold/accentPrimarystyling is derived fromtextStyle?.copyWith(...). If callers omittextStyle, the prefix ends up with no explicit style and won't reliably get the documented accent-colored/bold treatment, falling back to whatever the ambientDefaultTextStyleis.You may want to normalize through a base style so the prefix styling is consistent:
@override TextSpan formatDraftMessage( BuildContext context, DraftMessage draftMessage, { TextStyle? textStyle, }) { - final theme = StreamChatTheme.of(context); - final colorTheme = theme.colorTheme; - - return TextSpan( - text: getDraftPrefix(context), - style: textStyle?.copyWith( - fontWeight: FontWeight.bold, - color: colorTheme.accentPrimary, - ), - children: [ - const TextSpan(text: ' '), // Space between prefix and message - TextSpan(text: draftMessage.text, style: textStyle), - ], - ); + final theme = StreamChatTheme.of(context); + final colorTheme = theme.colorTheme; + final baseStyle = textStyle ?? DefaultTextStyle.of(context).style; + + return TextSpan( + text: getDraftPrefix(context), + style: baseStyle.copyWith( + fontWeight: FontWeight.bold, + color: colorTheme.accentPrimary, + ), + children: [ + const TextSpan(text: ' '), // Space between prefix and message + TextSpan(text: draftMessage.text, style: baseStyle), + ], + ); }This keeps behavior the same when a
textStyleis provided, while making the documented styling reliable when it is omitted.
📜 Review details
Configuration used: CodeRabbit 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.
📒 Files selected for processing (8)
packages/stream_chat_flutter/CHANGELOG.md(1 hunks)packages/stream_chat_flutter/lib/src/channel/stream_draft_message_preview_text.dart(1 hunks)packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart(1 hunks)packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart(6 hunks)packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart(1 hunks)packages/stream_chat_flutter/lib/stream_chat_flutter.dart(2 hunks)packages/stream_chat_flutter/test/src/channel/stream_draft_message_preview_text_test.dart(2 hunks)packages/stream_chat_flutter/test/src/channel/stream_message_preview_text_test.dart(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: xsahil03x
Repo: GetStream/stream-chat-flutter PR: 2394
File: packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart:82-92
Timestamp: 2025-09-25T08:19:01.469Z
Learning: In the Stream Chat Flutter library, when deleting a message that hasn't been sent to the server yet (message.remoteCreatedAt == null) or is bounced with error, the _deleteMessage method in channel.dart automatically handles deletion locally via _deleteLocalMessage without making API calls, preventing 404 errors and deletingFailed states.
Learnt from: xsahil03x
Repo: GetStream/stream-chat-flutter PR: 2394
File: packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart:82-92
Timestamp: 2025-09-25T08:19:01.469Z
Learning: In the Stream Chat Flutter library, when deleting a message that hasn't been sent to the server yet (message.remoteCreatedAt == null) or is bounced with error, the _deleteMessage method in channel.dart automatically handles deletion locally via _deleteLocalMessage without making API calls, preventing 404 errors and deletingFailed states.
📚 Learning: 2025-09-25T08:19:01.469Z
Learnt from: xsahil03x
Repo: GetStream/stream-chat-flutter PR: 2394
File: packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart:82-92
Timestamp: 2025-09-25T08:19:01.469Z
Learning: In the Stream Chat Flutter library, when deleting a message that hasn't been sent to the server yet (message.remoteCreatedAt == null) or is bounced with error, the _deleteMessage method in channel.dart automatically handles deletion locally via _deleteLocalMessage without making API calls, preventing 404 errors and deletingFailed states.
Applied to files:
packages/stream_chat_flutter/CHANGELOG.mdpackages/stream_chat_flutter/lib/stream_chat_flutter.dartpackages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dartpackages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dartpackages/stream_chat_flutter/lib/src/channel/stream_draft_message_preview_text.dartpackages/stream_chat_flutter/test/src/channel/stream_draft_message_preview_text_test.dart
📚 Learning: 2025-09-25T08:19:01.469Z
Learnt from: xsahil03x
Repo: GetStream/stream-chat-flutter PR: 2394
File: packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart:82-92
Timestamp: 2025-09-25T08:19:01.469Z
Learning: In the Stream Chat Flutter library, when deleting a message with MessageSendingStatus.failed or MessageSendingStatus.failed_update status, the _deleteMessage method in channel.dart automatically handles deletion locally via _deleteLocalMessage without making API calls, preventing 404 errors and deletingFailed states.
Applied to files:
packages/stream_chat_flutter/CHANGELOG.mdpackages/stream_chat_flutter/lib/stream_chat_flutter.dartpackages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dartpackages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dartpackages/stream_chat_flutter/lib/src/channel/stream_draft_message_preview_text.dartpackages/stream_chat_flutter/test/src/channel/stream_draft_message_preview_text_test.dart
⏰ 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). (11)
- GitHub Check: build (ios)
- GitHub Check: test
- GitHub Check: build (android)
- GitHub Check: analyze
- GitHub Check: format
- GitHub Check: stream_chat_localizations
- GitHub Check: stream_chat_flutter_core
- GitHub Check: stream_chat_flutter
- GitHub Check: stream_chat_persistence
- GitHub Check: stream_chat
- GitHub Check: analyze_legacy_versions
🔇 Additional comments (9)
packages/stream_chat_flutter/lib/src/channel/stream_draft_message_preview_text.dart (1)
21-28: Draft preview widget now cleanly delegates to configuration formatterUsing
StreamChatConfiguration.of(context).messagePreviewFormatter.formatDraftMessage(...)keeps draft previews in sync with global configuration and simplifies this widget. No issues spotted.packages/stream_chat_flutter/CHANGELOG.md (1)
5-8: Changelog accurately documents new message preview formatter hooksThe entry correctly names
MessagePreviewFormatter,StreamMessagePreviewFormatter, andStreamChatConfigurationData.messagePreviewFormatter, and describes their purpose in line with the implementation.packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart (1)
118-140: messagePreviewFormatter configuration wiring looks consistentThe
messagePreviewFormatterfield is correctly threaded through the factory (?? MessagePreviewFormatter()), the private constructor (required), andcopyWith(preserves existing value when omitted). The doc comment clearly states the default toMessagePreviewFormatter, matching usage.Also applies to: 151-163, 186-189
packages/stream_chat_flutter/test/src/channel/stream_message_preview_text_test.dart (2)
29-30: Injecting StreamChatConfigurationData into tests is a good extension pointThe optional
configDataparameter and wiring toStreamChat(streamChatConfigData: configData, ...)make it easy to exercise custom preview formatting in tests without touching production code, while keeping existing call sites unaffected.Also applies to: 38-44
545-671: Custom MessagePreviewFormatter tests cover key override scenariosThe
Custom MessagePreviewFormattergroup and_CustomMessagePreviewFormatterimplementation thoroughly validate overrides for current-user/group messages, polls, attachments (including a customproducttype), and direct messages. This gives strong confidence that downstream apps can customize previews and support custom attachments as intended by the new formatter API.Also applies to: 675-729
packages/stream_chat_flutter/lib/stream_chat_flutter.dart (1)
42-42: Exporting draft preview and formatter APIs makes customization accessibleAdding exports for
src/channel/stream_draft_message_preview_text.dartandsrc/utils/message_preview_formatter.dartcorrectly exposes the new draft preview widget and formatter interface/implementation to package consumers.Also applies to: 134-135
packages/stream_chat_flutter/lib/src/channel/stream_message_preview_text.dart (1)
34-43: Message preview widget now cleanly delegates to MessagePreviewFormatterUsing
StreamChatConfiguration.of(context).messagePreviewFormatter.formatMessage(...)after translation andreplaceMentionscentralizes preview logic (polls, attachments, group prefixes, etc.) in the formatter and keeps this widget simple. No behavioral issues stand out.packages/stream_chat_flutter/test/src/channel/stream_draft_message_preview_text_test.dart (1)
3-7: Draft preview tests correctly validate default and custom formatter behaviorThe updated helper wiring
StreamChat(streamChatConfigData: ...)plus_CustomMessagePreviewFormatter.getDraftPrefixgive good coverage of both the default'Draft:'prefix and a customized'✏️'prefix, confirming that draft previews respectStreamChatConfigurationData.messagePreviewFormatter.Also applies to: 14-22, 26-30, 55-75, 78-85
packages/stream_chat_flutter/lib/src/utils/message_preview_formatter.dart (1)
1-420: Centralized preview formatter design looks solid and extensibleThe
MessagePreviewFormatterinterface andStreamMessagePreviewFormatterimplementation nicely encapsulate preview behavior:_buildPreviewTextroutes by message type and sender/channel context,formatMessageAttachmentsmaps core attachment types to the expected icons/text (including audio/file/image/video/giphy/voiceRecording),formatPollMessagehandles voter/creator/name fallbacks, and mention bolding viasplitByRegExpkeeps styling localized to@usersegments. The protected hooks (regular/system/deleted/poll messages, current/direct/group prefixes, attachment and draft handling) give downstream apps clear extension points for custom attachment types and alternative prefixes without duplicating base logic.Also applies to: 442-541
29bc946 to
7999efa
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2441 +/- ##
==========================================
+ Coverage 64.19% 64.24% +0.04%
==========================================
Files 415 416 +1
Lines 25986 26022 +36
==========================================
+ Hits 16682 16718 +36
Misses 9304 9304 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Brazol
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Submit a pull request
Fixes: #2421
Description of the pull request
This PR introduces a new
MessagePreviewFormatterclass to allow developers to customize how message previews are formatted in the channel list.Previously, the formatting logic was hardcoded within the
StreamMessagePreviewTextandStreamDraftMessagePreviewTextwidgets. This change extracts that logic into a new, configurableStreamMessagePreviewFormatterclass.Key changes:
MessagePreviewFormatter: A new abstract class is introduced to define the contract for formatting message and draft message previews.StreamMessagePreviewFormatter: The default implementation that replicates the previous hardcoded behavior. It can be extended to override specific formatting methods (e.g., for polls, attachments, or group messages).StreamChatConfiguration: The configuration now accepts an optionalmessagePreviewFormatterinstance, allowing for app-wide customization.StreamMessagePreviewTextandStreamDraftMessagePreviewTextwidgets have been refactored to use the new formatter, significantly simplifying their implementation.Summary by CodeRabbit
New Features
Refactor
Tests