chore(repo): fix ci issues for flutter 3.44#2667
Conversation
* Remove `invariant_booleans` and `prefer_equal_for_default_values` lint rules * Add `deprecated_member_use` ignores for `cacheExtent` and `onReorder` usage
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (8)
📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds analyzer ignore directives to suppress deprecated_member_use warnings in multiple widgets, wraps a SwitchListTile in a Material for rounded/clipped styling, moves the message input background color into a surrounding Material, enforces a minimum Android compileSdkVersion and adds Gradle flags, removes the profile manifest package attribute and iOS MinimumOSVersion, and adjusts message-index lookups with regression tests to prevent duplicate messages. ChangesWidget lint suppressions and UI wrapper change
Sample app Android/iOS platform and build config updates
Channel indexing and tests
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
🧹 Nitpick comments (2)
packages/stream_chat_flutter/lib/src/misc/separated_reorderable_list_view.dart (1)
60-61: 💤 Low valueMigrate from deprecated
onReordercallback toonReorderItem.The
onReordercallback is deprecated as of Flutter 3.27 in favor ofonReorderItem. The new callback handles index adjustments automatically, eliminating the need for the manual adjustment logic at lines 66-67. Replace theonReordercallback withonReorderItemand remove the manual index adjustment workaround that accounts for Flutter issue#24786.🤖 Prompt for 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. In `@packages/stream_chat_flutter/lib/src/misc/separated_reorderable_list_view.dart` around lines 60 - 61, Replace the deprecated onReorder callback with the new onReorderItem callback in SeparatedReorderableListView (remove the // ignore: deprecated_member_use line), change the handler signature to match onReorderItem, and remove the manual index adjustment workaround that compensates for Flutter issue `#24786` (the logic that adjusts oldIndex/newIndex at lines 66-67). Ensure the new onReorderItem handler forwards the received indices directly to your reorder logic (or invokes the same internal reorder method) since onReorderItem already provides corrected indices.packages/stream_chat_flutter/lib/src/message_input/stream_message_input_attachment_list.dart (1)
372-373: 💤 Low valuePlan migration to
scrollCacheExtentfor Flutter 3.41+ compatibility.The
cacheExtentparameter is deprecated starting Flutter 3.41.0 (not yet relevant for the current 3.27.4 target, but worth tracking). When migrating, replace with:scrollCacheExtent: const ScrollCacheExtent.pixels(1040),Consider adding a TODO comment to track this for future upgrades.
🤖 Prompt for 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. In `@packages/stream_chat_flutter/lib/src/message_input/stream_message_input_attachment_list.dart` around lines 372 - 373, Replace the deprecated cacheExtent usage in the StreamMessageInputAttachmentList ListView (the line with "cacheExtent: 104 * 10") with the newer scrollCacheExtent API for future Flutter 3.41+ compatibility: remove the cacheExtent entry and add scrollCacheExtent: const ScrollCacheExtent.pixels(1040) in the same widget, and add a concise TODO above it noting this migration for Flutter 3.41+; ensure you keep the same intent (caching 10 items ahead) and the change is applied inside the StreamMessageInputAttachmentList build where the ListView is constructed.
🤖 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.
Nitpick comments:
In
`@packages/stream_chat_flutter/lib/src/message_input/stream_message_input_attachment_list.dart`:
- Around line 372-373: Replace the deprecated cacheExtent usage in the
StreamMessageInputAttachmentList ListView (the line with "cacheExtent: 104 *
10") with the newer scrollCacheExtent API for future Flutter 3.41+
compatibility: remove the cacheExtent entry and add scrollCacheExtent: const
ScrollCacheExtent.pixels(1040) in the same widget, and add a concise TODO above
it noting this migration for Flutter 3.41+; ensure you keep the same intent
(caching 10 items ahead) and the change is applied inside the
StreamMessageInputAttachmentList build where the ListView is constructed.
In
`@packages/stream_chat_flutter/lib/src/misc/separated_reorderable_list_view.dart`:
- Around line 60-61: Replace the deprecated onReorder callback with the new
onReorderItem callback in SeparatedReorderableListView (remove the // ignore:
deprecated_member_use line), change the handler signature to match
onReorderItem, and remove the manual index adjustment workaround that
compensates for Flutter issue `#24786` (the logic that adjusts oldIndex/newIndex
at lines 66-67). Ensure the new onReorderItem handler forwards the received
indices directly to your reorder logic (or invokes the same internal reorder
method) since onReorderItem already provides corrected indices.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 87d42164-b9df-4e1b-9b50-c550cd7d1937
📒 Files selected for processing (4)
analysis_options.yamlpackages/stream_chat_flutter/lib/src/message_input/stream_message_input_attachment_list.dartpackages/stream_chat_flutter/lib/src/misc/separated_reorderable_list_view.dartpackages/stream_chat_flutter_core/lib/src/paged_value_scroll_view.dart
💤 Files with no reviewable changes (1)
- analysis_options.yaml
Flutter 3.44 added a runtime assertion (list_tile.dart#_findIntermediateWidget) that fires whenever a ListTile with an onTap (e.g. SwitchListTile) has a ColoredBox/DecoratedBox-with-color ancestor before its nearest Material — because that ancestor paints over the Material surface where the ListTile draws its background and ink response. The widget previously wrapped the SwitchListTile and its optional children in a colored DecoratedBox. That triggered the assertion on every poll-creator golden test on Flutter 3.44. Replace the outer DecoratedBox with a Material widget carrying the same color + borderRadius. Material doubles as the ancestor the ListTile is looking for, so the assertion no longer fires; the visible panel that the optional children share with the tile is preserved. tileColor and the redundant shape are dropped from the inner SwitchListTile — Material owns the rounded surface now. melos.yaml SDK floor (Flutter >=3.27.4, Dart ^3.6.2) is unchanged; Material has supported color + borderRadius + clipBehavior since well before 3.27. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/stream_chat_flutter/lib/src/poll/creator/poll_switch_list_tile.dart (1)
64-64: ⚡ Quick winConsider using
Clip.hardEdgefor better performance.
Clip.antiAliasis more expensive thanClip.hardEdge. For simple rounded rectangles like this,Clip.hardEdgetypically provides sufficient visual quality with better rendering performance.⚡ Proposed change for improved performance
- clipBehavior: Clip.antiAlias, + clipBehavior: Clip.hardEdge,🤖 Prompt for 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. In `@packages/stream_chat_flutter/lib/src/poll/creator/poll_switch_list_tile.dart` at line 64, The widget currently sets clipBehavior: Clip.antiAlias which is more expensive; update the PollSwitchListTile (the widget that defines clipBehavior) to use clipBehavior: Clip.hardEdge instead for this simple rounded-rect clipping to improve rendering performance, making the change where the Clip.antiAlias value is assigned in the build/constructor of PollSwitchListTile.
🤖 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.
Nitpick comments:
In
`@packages/stream_chat_flutter/lib/src/poll/creator/poll_switch_list_tile.dart`:
- Line 64: The widget currently sets clipBehavior: Clip.antiAlias which is more
expensive; update the PollSwitchListTile (the widget that defines clipBehavior)
to use clipBehavior: Clip.hardEdge instead for this simple rounded-rect clipping
to improve rendering performance, making the change where the Clip.antiAlias
value is assigned in the build/constructor of PollSwitchListTile.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: af12aab8-8a21-4b01-8dc9-7054778079e8
⛔ Files ignored due to path filters (138)
packages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_idle_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playing_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playing_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/attachment/goldens/ci/stream_voice_recording_attachment_playlist_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_3.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/gradient_avatar_issue_2369.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/group_avatar_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/user_avatar_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/avatars/goldens/ci/user_avatar_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/attachment_modal_sheet_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/edit_message_sheet_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/bottom_sheets/goldens/ci/error_alert_sheet_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/channel/goldens/ci/channel_header_bottom_widget.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/download_menu_item_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/context_menu_items/goldens/ci/stream_chat_context_menu_item_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/dialogs/goldens/ci/confirmation_dialog_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/dialogs/goldens/ci/delete_message_dialog_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/dialogs/goldens/ci/message_dialog_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_footer_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/gallery/goldens/ci/gallery_header_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/icons/goldens/ci/stream_svg_icon_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/icons/goldens/ci/stream_svg_icon_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/sending_indicator_3.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/upload_progress_indicator_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/upload_progress_indicator_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/indicators/goldens/ci/upload_progress_indicator_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_idle_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_idle_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_hold_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_locked_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/audio_recorder/goldens/ci/stream_audio_recorder_button_recording_stopped_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/attachment_button_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/clear_input_item_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/command_button_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/countdown_button_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/dm_checkbox_0.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/dm_checkbox_1.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_input/goldens/ci/dm_checkbox_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_custom.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/goldens/ci/deleted_message_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/goldens/ci/message_text.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_custom_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_empty_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_inverted_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_less_data_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_progress_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_audio_waveform_slider_progress_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/stream_timestamp_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/system_message_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_delete_option_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_delete_option_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_error_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_option_reorderable_list_view_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_error_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/poll_question_text_field_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/creator/goldens/ci/stream_poll_creator_full_screen_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_error.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_option_reorderable_list_view_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_error.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/poll_question_text_field_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_creator_full_screen_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_add_comment_dialog_with_initial_value_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_end_vote_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_long_question_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_all_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_disabled_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_limited_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_header_subtitle_voting_mode_unique_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/poll_suggest_option_dialog_with_initial_option_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/draft_scroll_view/goldens/ci/stream_draft_list_tile_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_unread_threads_banner_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_unread_threads_banner_light.pngis excluded by!**/*.png
📒 Files selected for processing (1)
packages/stream_chat_flutter/lib/src/poll/creator/poll_switch_list_tile.dart
Some transitive dependencies pulled in by the sample app require compileSdk >= 36 via their AAR metadata, but Flutter's bundled compileSdkVersion is still 35, so the build fails with: CheckAarMetadataWorkAction: Dependency '<lib>' requires libraries and applications that depend on it to compile against version 36 or later of the Android APIs. Pin a floor of 36 via Math.max(flutter.compileSdkVersion, 36) in both the :app module and the root subprojects block (so plugin projects pick it up too). The Math.max means we'll automatically follow Flutter's version once it ships 36+ without another change here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small, version-safe migrations Flutter applies automatically the first time the sample_app is built on a recent enough toolchain: - android/app/src/profile/AndroidManifest.xml: drop the deprecated `package="..."` attribute. AGP 7.4+ reads the package name from the module's `namespace` in build.gradle and warns about the attribute. - android/gradle.properties: add `android.builtInKotlin=false` and `android.newDsl=false`. These are opt-outs the Flutter migrator writes to keep the existing Kotlin/DSL behaviour stable; older AGP that doesn't recognise them just warns. - ios/Flutter/AppFrameworkInfo.plist: drop `MinimumOSVersion=12.0`. The Xcode project's deployment target is the source of truth on every supported Flutter version, so the plist entry is redundant. All three are safe across the monorepo's supported Flutter range (>=3.27.4 in melos.yaml). The iOS/macOS Swift Package Manager migration that Flutter also wants to apply is intentionally left uncommitted because SPM was opt-in on 3.27.4 and would churn or break local builds for devs on the floor version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Flutter 3.44 asserts when a ListTile (or SwitchListTile/CheckboxListTile) walks up the tree and encounters a DecoratedBox with a non-transparent color before reaching its nearest Material ancestor. The intermediate colored DecoratedBox in StreamMessageInput tripped this for DmCheckboxListTile when rendered inside a thread. Moving inputBackgroundColor onto the outer Material removes the intermediate color while preserving the custom shadow on DecoratedBox. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2667 +/- ##
==========================================
- Coverage 65.29% 65.29% -0.01%
==========================================
Files 423 423
Lines 26642 26635 -7
==========================================
- Hits 17397 17390 -7
Misses 9245 9245 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The previous fast-path in `ChannelClientState.updateMessage` returned -1 (treat as insert) whenever the incoming message's `createdAt` was later than `messages.last.createdAt`. That assumption breaks for the optimistic-send + server-echo flow and, more visibly, after a retry-from-offline once another message has slipped in between the local copy and the tail — the locally-sent message is no longer at the end, so the id-by-id scan was skipped and `sortedUpsertAt(-1, ...)` appended a duplicate. Downstream, `RenderSliverMultiBoxAdaptor._debugVerifyChildOrder` crashed because the message list now had two children keyed by the same `message.id`. Replace the shortcut with a single `lastIndexWhere` scan. Walking from the tail keeps the common-case latency low (updates almost always target a recent message) and remains correct when the locally-inserted copy is buried mid-list. Two regression tests in `channel_test.dart` route through `channel.sendMessage` with a mocked client and fire a `message.new` event afterward — one with the local copy still at the tail, one with another message arriving in between (the offline-retry shape). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`getFirstUnreadMessage` looks up the user's last-read message in the channel's canonical message list (ascending by `createdAt`, newest at the tail). The last-read pointer is almost always close to the most recent message — there's already a fast-path for the exact-tail case on the line above. Swap `indexWhere` for `lastIndexWhere` so the general case also finishes in a few comparisons instead of walking the whole buffer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings master's QA / security / perf work into the v10 design-refresh branch. Highlights of what landed in v10 from master: LLC (`stream_chat`) - `Client.queryDrafts` now forwards `filter` (#2647). - `Client.queryChannels` coalesces concurrent identical queries via the new `InFlightCache<K, V>` (#2652). - `SortedListX` / `ListX` extensions added in `list_extensions.dart`; duplicate-keyed inputs are tolerated by `merge` (#2660). v10's `IterableMergeExtension.merge` / `.mergeFrom` are kept — `SortedListX` is on `List` and routes there for the new perf paths; the old extension still serves `Iterable<T>` callers in v10. - `ChannelClientState._checkExpiredAttachmentMessages` removed (#2653); v10's `StreamImageCDN.cacheKey` already keeps the image cache valid across signed-URL rotations. - `ChannelClientState.updateChannelState` now identity-short-circuits when `updatedState.messages` is null or the same reference, so downstream `.distinct()` listeners can skip rebuilds. - Reaction listeners now dispatch via `_findMessage` (parentId-aware) while keeping v10's `addMyReaction` / `deleteMyReaction` semantics. `stream_chat_flutter_core` - `BetterStreamBuilder` correctness fixes: mounted guard, error reporting via `FlutterError.reportError`, identity-equal emission gating (#2651). - `MessageListCore` caches its `messagesStream` / `_initialMessages` as fields instead of recomputing in `build()` (#2651). `defaultMessageFilter` takes an optional `currentUserId`. - `StreamChatCore` debounces connectivity events to 3 s (#2652). `stream_chat_flutter` - `scrollable_positioned_list/`: master version taken in full. Bounded `_keyToIndexMap`, `isScrolling` / `isScrollingListenable`, `itemKeyBuilder` anchor preservation, fit-anchor fallback in `UnboundedRenderViewport`, sensible defaults on `scrollTo` (#2651). - `tld.dart` removed (#2654); `StreamMessageComposer` relaxed its URL regex from `[a-z]{2,4}` to `[a-z]{2,}` and dropped the `isValidTLD` filter at both call sites. - `StreamMessageListView` and `separated_reorderable_list_view`: v10's design-refresh version retained. v10 already covers the functional surface; master's identity-preserving micro-optimizations to `updateMessage` are a follow-up. CI / repo - Path/draft gating job (`gate`) added to `legacy_version_analyze`, `check_db_entities`, and `stream_flutter_workflow` (#2669). - Flutter 3.44 fixes (#2667), pana / build cleanups (#2656), local-setup CI fixes (#2650). - `melos.yaml`: kept v10's higher floors; added `firebase_crashlytics` (master's #2665); dropped `sentry_flutter` (per master). Notes / follow-ups - `sample_app/`: v10's redesigned app retained. The Sentry → Firebase Crashlytics migration (#2665) applies to master's pre-redesign sample app and was not ported here; left for a separate pass. - `channel_test.dart` `updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deleted` is marked `skip:` — v10's `_updateMessages` reconstructs the channel list via `_mergeMessagesIntoExisting`, so identity is not preserved on non-deletion edits. Functional behavior matches master. - `goldens/`: deleted-on-v10 goldens kept deleted; modified-on-both goldens kept at v10's bytes (the redesigned UI is the source of truth). - `stream_message_composer.dart` had `SizeTransition(alignment:)` which was never a valid parameter — switched to `axisAlignment: -1` (the Flutter API the v10 author intended). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings master's QA / security / perf work into the v10 design-refresh branch. Highlights of what landed in v10 from master: LLC (`stream_chat`) - `Client.queryDrafts` now forwards `filter` (#2647). - `Client.queryChannels` coalesces concurrent identical queries via the new `InFlightCache<K, V>` (#2652). - `SortedListX` / `ListX` extensions added in `list_extensions.dart`; duplicate-keyed inputs are tolerated by `merge` (#2660). v10's `IterableMergeExtension.merge` / `.mergeFrom` are kept — `SortedListX` is on `List` and routes there for the new perf paths; the old extension still serves `Iterable<T>` callers in v10. - `ChannelClientState._checkExpiredAttachmentMessages` removed (#2653); v10's `StreamImageCDN.cacheKey` already keeps the image cache valid across signed-URL rotations. - `ChannelClientState.updateChannelState` now identity-short-circuits when `updatedState.messages` is null or the same reference, so downstream `.distinct()` listeners can skip rebuilds. - Reaction listeners now dispatch via `_findMessage` (parentId-aware) while keeping v10's `addMyReaction` / `deleteMyReaction` semantics. `stream_chat_flutter_core` - `BetterStreamBuilder` correctness fixes: mounted guard, error reporting via `FlutterError.reportError`, identity-equal emission gating (#2651). - `MessageListCore` caches its `messagesStream` / `_initialMessages` as fields instead of recomputing in `build()` (#2651). `defaultMessageFilter` takes an optional `currentUserId`. - `StreamChatCore` debounces connectivity events to 3 s (#2652). `stream_chat_flutter` - `scrollable_positioned_list/`: master version taken in full. Bounded `_keyToIndexMap`, `isScrolling` / `isScrollingListenable`, `itemKeyBuilder` anchor preservation, fit-anchor fallback in `UnboundedRenderViewport`, sensible defaults on `scrollTo` (#2651). - `tld.dart` removed (#2654); `StreamMessageComposer` relaxed its URL regex from `[a-z]{2,4}` to `[a-z]{2,}` and dropped the `isValidTLD` filter at both call sites. - `StreamMessageListView` and `separated_reorderable_list_view`: v10's design-refresh version retained. v10 already covers the functional surface; master's identity-preserving micro-optimizations to `updateMessage` are a follow-up. CI / repo - Path/draft gating job (`gate`) added to `legacy_version_analyze`, `check_db_entities`, and `stream_flutter_workflow` (#2669). - Flutter 3.44 fixes (#2667), pana / build cleanups (#2656), local-setup CI fixes (#2650). - `melos.yaml`: kept v10's higher floors; added `firebase_crashlytics` (master's #2665); dropped `sentry_flutter` (per master). Notes / follow-ups - `sample_app/`: v10's redesigned app retained. The Sentry → Firebase Crashlytics migration (#2665) applies to master's pre-redesign sample app and was not ported here; left for a separate pass. - `channel_test.dart` `updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deleted` is marked `skip:` — v10's `_updateMessages` reconstructs the channel list via `_mergeMessagesIntoExisting`, so identity is not preserved on non-deletion edits. Functional behavior matches master. - `goldens/`: deleted-on-v10 goldens kept deleted; modified-on-both goldens kept at v10's bytes (the redesigned UI is the source of truth). - `stream_message_composer.dart` had `SizeTransition(alignment:)` which was never a valid parameter — switched to `axisAlignment: -1` (the Flutter API the v10 author intended). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings master's QA / security / perf work into the v10 design-refresh branch. Highlights of what landed in v10 from master: LLC (`stream_chat`) - `Client.queryDrafts` now forwards `filter` (#2647). - `Client.queryChannels` coalesces concurrent identical queries via the new `InFlightCache<K, V>` (#2652). - `SortedListX` / `ListX` extensions added in `list_extensions.dart`; duplicate-keyed inputs are tolerated by `merge` (#2660). v10's `IterableMergeExtension.merge` / `.mergeFrom` are kept — `SortedListX` is on `List` and routes there for the new perf paths; the old extension still serves `Iterable<T>` callers in v10. - `ChannelClientState._checkExpiredAttachmentMessages` removed (#2653); v10's `StreamImageCDN.cacheKey` already keeps the image cache valid across signed-URL rotations. - `ChannelClientState.updateChannelState` now identity-short-circuits when `updatedState.messages` is null or the same reference, so downstream `.distinct()` listeners can skip rebuilds. - Reaction listeners now dispatch via `_findMessage` (parentId-aware) while keeping v10's `addMyReaction` / `deleteMyReaction` semantics. `stream_chat_flutter_core` - `BetterStreamBuilder` correctness fixes: mounted guard, error reporting via `FlutterError.reportError`, identity-equal emission gating (#2651). - `MessageListCore` caches its `messagesStream` / `_initialMessages` as fields instead of recomputing in `build()` (#2651). `defaultMessageFilter` takes an optional `currentUserId`. - `StreamChatCore` debounces connectivity events to 3 s (#2652). `stream_chat_flutter` - `scrollable_positioned_list/`: master version taken in full. Bounded `_keyToIndexMap`, `isScrolling` / `isScrollingListenable`, `itemKeyBuilder` anchor preservation, fit-anchor fallback in `UnboundedRenderViewport`, sensible defaults on `scrollTo` (#2651). - `tld.dart` removed (#2654); `StreamMessageComposer` relaxed its URL regex from `[a-z]{2,4}` to `[a-z]{2,}` and dropped the `isValidTLD` filter at both call sites. - `StreamMessageListView` and `separated_reorderable_list_view`: v10's design-refresh version retained. v10 already covers the functional surface; master's identity-preserving micro-optimizations to `updateMessage` are a follow-up. CI / repo - Path/draft gating job (`gate`) added to `legacy_version_analyze`, `check_db_entities`, and `stream_flutter_workflow` (#2669). - Flutter 3.44 fixes (#2667), pana / build cleanups (#2656), local-setup CI fixes (#2650). - `melos.yaml`: kept v10's higher floors; added `firebase_crashlytics` (master's #2665); dropped `sentry_flutter` (per master). Notes / follow-ups - `sample_app/`: v10's redesigned app retained. The Sentry → Firebase Crashlytics migration (#2665) applies to master's pre-redesign sample app and was not ported here; left for a separate pass. - `channel_test.dart` `updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deleted` is marked `skip:` — v10's `_updateMessages` reconstructs the channel list via `_mergeMessagesIntoExisting`, so identity is not preserved on non-deletion edits. Functional behavior matches master. - `goldens/`: deleted-on-v10 goldens kept deleted; modified-on-both goldens kept at v10's bytes (the redesigned UI is the source of truth). - `stream_message_composer.dart` had `SizeTransition(alignment:)` which was never a valid parameter — switched to `axisAlignment: -1` (the Flutter API the v10 author intended). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings master's QA / security / perf work into the v10 design-refresh branch. Highlights of what landed in v10 from master: LLC (`stream_chat`) - `Client.queryDrafts` now forwards `filter` (#2647). - `Client.queryChannels` coalesces concurrent identical queries via the new `InFlightCache<K, V>` (#2652). - `SortedListX` / `ListX` extensions added in `list_extensions.dart`; duplicate-keyed inputs are tolerated by `merge` (#2660). v10's `IterableMergeExtension.merge` / `.mergeFrom` are kept — `SortedListX` is on `List` and routes there for the new perf paths; the old extension still serves `Iterable<T>` callers in v10. - `ChannelClientState._checkExpiredAttachmentMessages` removed (#2653); v10's `StreamImageCDN.cacheKey` already keeps the image cache valid across signed-URL rotations. - `ChannelClientState.updateChannelState` now identity-short-circuits when `updatedState.messages` is null or the same reference, so downstream `.distinct()` listeners can skip rebuilds. - Reaction listeners now dispatch via `_findMessage` (parentId-aware) while keeping v10's `addMyReaction` / `deleteMyReaction` semantics. `stream_chat_flutter_core` - `BetterStreamBuilder` correctness fixes: mounted guard, error reporting via `FlutterError.reportError`, identity-equal emission gating (#2651). - `MessageListCore` caches its `messagesStream` / `_initialMessages` as fields instead of recomputing in `build()` (#2651). `defaultMessageFilter` takes an optional `currentUserId`. - `StreamChatCore` debounces connectivity events to 3 s (#2652). `stream_chat_flutter` - `scrollable_positioned_list/`: master version taken in full. Bounded `_keyToIndexMap`, `isScrolling` / `isScrollingListenable`, `itemKeyBuilder` anchor preservation, fit-anchor fallback in `UnboundedRenderViewport`, sensible defaults on `scrollTo` (#2651). - `tld.dart` removed (#2654); `StreamMessageComposer` relaxed its URL regex from `[a-z]{2,4}` to `[a-z]{2,}` and dropped the `isValidTLD` filter at both call sites. - `StreamMessageListView` and `separated_reorderable_list_view`: v10's design-refresh version retained. v10 already covers the functional surface; master's identity-preserving micro-optimizations to `updateMessage` are a follow-up. CI / repo - Path/draft gating job (`gate`) added to `legacy_version_analyze`, `check_db_entities`, and `stream_flutter_workflow` (#2669). - Flutter 3.44 fixes (#2667), pana / build cleanups (#2656), local-setup CI fixes (#2650). - `melos.yaml`: kept v10's higher floors; added `firebase_crashlytics` (master's #2665); dropped `sentry_flutter` (per master). Notes / follow-ups - `sample_app/`: v10's redesigned app retained. The Sentry → Firebase Crashlytics migration (#2665) applies to master's pre-redesign sample app and was not ported here; left for a separate pass. - `channel_test.dart` `updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deleted` is marked `skip:` — v10's `_updateMessages` reconstructs the channel list via `_mergeMessagesIntoExisting`, so identity is not preserved on non-deletion edits. Functional behavior matches master. - `goldens/`: deleted-on-v10 goldens kept deleted; modified-on-both goldens kept at v10's bytes (the redesigned UI is the source of truth). - `stream_message_composer.dart` had `SizeTransition(alignment:)` which was never a valid parameter — switched to `axisAlignment: -1` (the Flutter API the v10 author intended). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary by CodeRabbit